ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-09-09 04:36:49
Exec Total Coverage
Lines: 4178 5231 79.9%
Functions: 293 332 88.3%
Branches: 3228 5328 60.6%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 416 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 416 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 576 void maps_init_game_vars()
67 {
68 576 viewport = {};
69 576 viewport_mode = ViewportMode::CenterAndBound;
70 576 viewport_sprite_uid = 1;
71 576 currscr_for_passive_subscr = -1;
72 576 }
73
74 static region_ids_t current_region_ids;
75
76 // Returns true if the (map, screen) is inside a scrolling region.
77 14619034 static bool is_in_scrolling_region(int map, int screen)
78 {
79 14619034 return get_region_id(map, screen) != 0;
80 }
81
82 bool is_in_screenscrolling_region(int screen)
83 {
84 if (!screenscrolling) return false;
85
86 int x = screen % 16;
87 int y = screen / 16;
88 return
89 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
90 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
91 }
92
93 8238597514 bool is_in_scrolling_region()
94 {
95 8238597514 return cur_region.screen_count > 1;
96 }
97
98 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
99 {
100
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_in_scrolling_region(map, scr)) return false;
101 1460 int region_id = get_region_id(map, region_origin_scr);
102
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
103 2232 }
104
105 138013324 bool is_in_current_region(int map, int screen)
106 {
107
2/2
✓ Branch 0 taken 1573 times.
✓ Branch 1 taken 138011751 times.
138013324 if (map != cur_map)
108 1573 return false;
109
110
3/4
✓ Branch 0 taken 138011751 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 137999538 times.
✓ Branch 3 taken 12213 times.
138011751 if (screen >= 0 && screen < 128)
111 137999538 return screen_in_current_region[screen];
112
113 12213 return screen == cur_screen;
114 138013324 }
115
116 211035290 bool is_in_current_region(int screen)
117 {
118
5/6
✓ Branch 0 taken 209919788 times.
✓ Branch 1 taken 1115502 times.
✓ Branch 2 taken 1115502 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1115497 times.
211035290 return screen == cur_screen || (screen >= 0 && screen < 128 && screen_in_current_region[screen]);
119 }
120
121 29491991 bool is_in_current_region(mapscr* scr)
122 {
123
2/2
✓ Branch 0 taken 14690 times.
✓ Branch 1 taken 29477301 times.
29491991 return scr->map == cur_map && is_in_current_region(scr->screen);
124 }
125
126 76844033 bool is_extended_height_mode()
127 {
128
2/2
✓ Branch 0 taken 76593899 times.
✓ Branch 1 taken 250134 times.
76844033 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
129 }
130
131 // Returns 0 if this is not a scrolling region.
132 15661076 int get_region_id(int map, int screen)
133 {
134
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 15259641 times.
15661076 if (screen >= 128) return 0;
135
2/2
✓ Branch 0 taken 15258541 times.
✓ Branch 1 taken 1100 times.
15259641 if (map == cur_region.map) return current_region_ids[screen];
136
137 1100 return Regions[map].get_region_id(screen);
138 15661076 }
139
140 982758 int get_current_region_id()
141 {
142 982758 return get_region_id(cur_map, cur_screen);
143 }
144
145 64216 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
146 {
147 64216 region.map = map;
148
149
2/2
✓ Branch 0 taken 63942 times.
✓ Branch 1 taken 274 times.
64216 if (!is_in_scrolling_region(map, screen))
150 {
151 63942 region.region_id = 0;
152 63942 region.origin_screen = screen;
153 63942 region.origin_screen_x = screen % 16;
154 63942 region.origin_screen_y = screen / 16;
155 63942 region.screen_width = 1;
156 63942 region.screen_height = 1;
157 63942 region.screen_count = 1;
158 63942 region.width = 256;
159 63942 region.height = 176;
160 63942 region_scr_dx = 0;
161 63942 region_scr_dy = 0;
162 63942 return;
163 }
164
165 274 int input_scr_x = screen % 16;
166 274 int input_scr_y = screen / 16;
167
168 // For the given screen, find the top-left corner of its region.
169 274 int origin_scr_x = input_scr_x;
170 274 int origin_scr_y = input_scr_y;
171 274 int origin_scr = screen;
172
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
173 {
174
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
175 160 origin_scr_x--;
176 }
177
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
178 {
179
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
180 234 origin_scr_y--;
181 }
182 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
183
184 // Now find the bottom-right corner.
185 274 int region_scr_right = origin_scr_x;
186
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
187 {
188
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
189 368 region_scr_right++;
190 }
191 274 int region_scr_bottom = origin_scr_y;
192
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
193 {
194
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
195 582 region_scr_bottom++;
196 }
197
198 274 region.region_id = get_region_id(map, origin_scr);
199 274 region.origin_screen = origin_scr;
200 274 region.origin_screen_x = origin_scr_x;
201 274 region.origin_screen_y = origin_scr_y;
202 274 region.screen_width = region_scr_right - origin_scr_x + 1;
203 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
204 274 region.screen_count = region.screen_width * region.screen_height;
205 274 region.width = 256 * region.screen_width;
206 274 region.height = 176 * region.screen_height;
207 274 region_scr_dx = input_scr_x - origin_scr_x;
208 274 region_scr_dy = input_scr_y - origin_scr_y;
209
210 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
211 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
212 64216 }
213
214 35855 void load_region(int dmap, int screen)
215 {
216 35855 clear_temporary_screens();
217
218 35855 int map = DMaps[dmap].map;
219 35855 current_region_ids = Regions[map].get_all_region_ids();
220
221 35855 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
222 35855 cur_screen = cur_region.origin_screen;
223 35855 world_w = cur_region.width;
224 35855 world_h = cur_region.height;
225 35855 region_scr_count = cur_region.screen_count;
226 35855 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
227 35855 region_num_rpos = cur_region.screen_count*176;
228 35855 scrolling_maze_last_solved_screen = 0;
229
230 35855 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
231
2/2
✓ Branch 0 taken 36089 times.
✓ Branch 1 taken 35855 times.
71944 for (int x = 0; x < cur_region.screen_width; x++)
232 {
233
2/2
✓ Branch 0 taken 37099 times.
✓ Branch 1 taken 36089 times.
73188 for (int y = 0; y < cur_region.screen_height; y++)
234 {
235 37099 int screen = cur_screen + x + y*16;
236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37099 times.
37099 if (screen < 136)
237 {
238 37099 screen_in_current_region[screen] = true;
239 37099 }
240 37099 }
241 36089 }
242
243 35855 mark_current_region_handles_dirty();
244 35855 }
245
246 35855 static void prepare_current_region_handles()
247 {
248 35855 current_region_rpos_handles_dirty = false;
249 35855 current_region_screen_count = 0;
250
2/2
✓ Branch 0 taken 36203 times.
✓ Branch 1 taken 35855 times.
72058 for (int y = 0; y < cur_region.screen_height; y++)
251 {
252
2/2
✓ Branch 0 taken 37099 times.
✓ Branch 1 taken 36203 times.
73302 for (int x = 0; x < cur_region.screen_width; x++)
253 {
254 37099 int screen = cur_screen + x + y*16;
255 37099 int index_start = current_region_screen_count;
256
2/2
✓ Branch 0 taken 37099 times.
✓ Branch 1 taken 259693 times.
296792 for (int layer = 0; layer <= 6; layer++)
257 {
258 259693 mapscr* scr = get_scr_layer(screen, layer);
259
2/2
✓ Branch 0 taken 86181 times.
✓ Branch 1 taken 173512 times.
259693 if (!scr->is_valid())
260 {
261
1/2
✓ Branch 0 taken 173512 times.
✗ Branch 1 not taken.
173512 if (layer == 0) break;
262 173512 continue;
263 }
264
265 86181 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
266 86181 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
267 86181 current_region_screen_count += 1;
268 86181 }
269
270 37099 int num_handles_for_scr = current_region_screen_count - index_start;
271 37099 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
272 37099 }
273 36203 }
274 35855 }
275
276 1635436324 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
277 {
278 DCHECK(!current_region_rpos_handles_dirty);
279 1635436324 return {current_region_rpos_handles, current_region_screen_count};
280 }
281
282 11129700 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
283 {
284 DCHECK(!current_region_rpos_handles_dirty);
285
2/4
✓ Branch 0 taken 11129700 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11129700 times.
11129700 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
286 return {nullptr, 0};
287
288
2/2
✓ Branch 0 taken 65877 times.
✓ Branch 1 taken 11063823 times.
11129700 if (cur_screen >= 0x80)
289 {
290 DCHECK(scr == origin_scr);
291 65877 return {nullptr, 0};
292 }
293
294 DCHECK(is_in_current_region(scr));
295 11063823 return current_region_rpos_handles_scr[scr->screen];
296 11129700 }
297
298 35855 void mark_current_region_handles_dirty()
299 {
300 35855 current_region_rpos_handles_dirty = true;
301 35855 }
302
303 64943 void delete_temporary_screens(mapscr** screens)
304 {
305
2/2
✓ Branch 0 taken 61825736 times.
✓ Branch 1 taken 64943 times.
61890679 for (int i = 0; i < 136*7; i++)
306 {
307
2/2
✓ Branch 0 taken 255689 times.
✓ Branch 1 taken 61570047 times.
61825736 if (!screens[i])
308 61570047 continue;
309
310 255689 mapscr* scr = screens[i];
311 255689 int num_ffcs = scr->numFFC();
312
2/2
✓ Branch 0 taken 7619480 times.
✓ Branch 1 taken 255689 times.
7875169 for (int i = 0; i < num_ffcs; i++)
313 {
314 7619480 sprite* ffc = &scr->ffcs[i];
315
2/2
✓ Branch 0 taken 7617623 times.
✓ Branch 1 taken 1857 times.
7619480 if (ffc->uid)
316 1857 FFCore.release_sprite_owned_objects(ffc->uid);
317 7619480 }
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 255689 times.
255689 delete scr;
319 255689 screens[i] = NULL;
320 255689 }
321 64943 }
322
323 36993 void clear_temporary_screens()
324 {
325 36993 delete_temporary_screens(temporary_screens);
326 36993 origin_scr = nullptr;
327 36993 hero_scr = nullptr;
328 36993 }
329
330 27954 std::vector<mapscr*> take_temporary_scrs()
331 {
332
1/2
✓ Branch 0 taken 27954 times.
✗ Branch 1 not taken.
27954 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
333
2/2
✓ Branch 0 taken 27954 times.
✓ Branch 1 taken 26612208 times.
26640162 for (int i = 0; i < 136*7; i++)
334 26612208 temporary_screens[i] = nullptr;
335
336 27954 return screens;
337
1/2
✓ Branch 0 taken 27954 times.
✗ Branch 1 not taken.
27954 }
338
339 14552946 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
340 {
341 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
342
343
2/2
✓ Branch 0 taken 14506364 times.
✓ Branch 1 taken 46582 times.
14552946 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
344 14552946 viewport.w = 256;
345 14552946 viewport.h = 176 + (extended_height_mode ? 56 : 0);
346
347
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 14552586 times.
14552946 if (viewport_mode == ViewportMode::Script)
348 360 return;
349
350
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 14506424 times.
14552586 if (!is_in_scrolling_region(DMaps[dmap].map, screen))
351 {
352 14506424 viewport.x = 0;
353 14506424 viewport.y = 0;
354 14506424 }
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
356 {
357 // Clamp the viewport to the edges of the region.
358
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
359
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
360 46162 }
361 else if (viewport_mode == ViewportMode::Center)
362 {
363 viewport.x = x - viewport.w/2;
364 viewport.y = y - viewport.h/2;
365 }
366 14552946 }
367
368 14552435 sprite* get_viewport_sprite()
369 {
370 14552435 sprite* spr = sprite::getByUID(viewport_sprite_uid);
371
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 14552429 times.
14552435 if (!spr)
372 {
373 6 viewport_sprite_uid = 1; // Hero uid.
374 6 spr = &Hero;
375 6 }
376
377 14552435 return spr;
378 }
379
380 6 void set_viewport_sprite(sprite* spr)
381 {
382 6 viewport_sprite_uid = spr->uid;
383 6 }
384
385 14524481 void update_viewport()
386 {
387 14524481 sprite* spr = get_viewport_sprite();
388 14524481 int x = spr->x + spr->txsz*16/2;
389 14524481 int y = spr->y + spr->tysz*16/2;
390 14524481 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
391 14524481 }
392
393 // TODO: should add a moveflag to sprites to configure the size of this rect (or effectively disable
394 // freezing if the rect returns is large enough). See:
395 // https://discord.com/channels/876899628556091432/1358483603700449581
396 // https://discord.com/channels/876899628556091432/1130384911983980554
397 //
398 85884049 viewport_t get_sprite_freeze_rect()
399 {
400 85884049 viewport_t freeze_rect = viewport;
401 85884049 int tile_buffer = 3;
402 85884049 freeze_rect.w += 16 * tile_buffer * 2;
403 85884049 freeze_rect.h += 16 * tile_buffer * 2;
404 85884049 freeze_rect.x -= 16 * tile_buffer;
405 85884049 freeze_rect.y -= 16 * tile_buffer;
406 85884049 return freeze_rect;
407 }
408
409 4722 mapscr* determine_hero_screen_from_coords()
410 {
411 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
412 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
413 4722 int dx = x / 256;
414 4722 int dy = y / 176;
415 4722 return get_scr(cur_screen + dx + dy * 16);
416 }
417
418 26924 bool edge_of_region(direction dir)
419 {
420
2/2
✓ Branch 0 taken 26844 times.
✓ Branch 1 taken 80 times.
26924 if (!is_in_scrolling_region()) return true;
421
422 80 int screen_x = Hero.current_screen % 16;
423 80 int screen_y = Hero.current_screen / 16;
424
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
425
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
426
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
427
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
428
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
429 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
430 26924 }
431
432 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
433 // Coordinates are clamped to the world bounds.
434 321835180 int get_screen_for_world_xy(int x, int y)
435 {
436
2/2
✓ Branch 0 taken 300696200 times.
✓ Branch 1 taken 21138980 times.
321835180 if (!is_in_scrolling_region())
437 300696200 return cur_screen;
438
439 21138980 int dx = std::clamp(x, 0, world_w - 1) / 256;
440 21138980 int dy = std::clamp(y, 0, world_h - 1) / 176;
441 21138980 int origin_screen_x = cur_screen % 16;
442 21138980 int origin_screen_y = cur_screen / 16;
443 21138980 int scr_x = origin_screen_x + dx;
444 21138980 int scr_y = origin_screen_y + dy;
445 21138980 return map_scr_xy_to_index(scr_x, scr_y);
446 321835180 }
447
448 31102052 int get_screen_for_rpos(rpos_t rpos)
449 {
450 31102052 int origin_screen_x = cur_screen % 16;
451 31102052 int origin_screen_y = cur_screen / 16;
452 31102052 int screen = static_cast<int32_t>(rpos) / 176;
453 31102052 int scr_x = origin_screen_x + screen%cur_region.screen_width;
454 31102052 int scr_y = origin_screen_y + screen/cur_region.screen_width;
455 31102052 return map_scr_xy_to_index(scr_x, scr_y);
456 }
457
458 775305591 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
459 {
460 DCHECK_LAYER_ZERO_INDEX(layer);
461
2/2
✓ Branch 0 taken 744341499 times.
✓ Branch 1 taken 30964092 times.
775305591 if (!is_in_scrolling_region())
462 744341499 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
463 30964092 int screen = get_screen_for_rpos(rpos);
464 30964092 mapscr* scr = get_scr_layer(screen, layer);
465 30964092 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
466 775305591 }
467
468 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
469 // Coordinates are clamped to the world bounds.
470 3124507639 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
471 {
472 3124507639 x = std::clamp(x, 0, world_w - 1);
473 3124507639 y = std::clamp(y, 0, world_h - 1);
474
475 DCHECK_LAYER_ZERO_INDEX(layer);
476
2/2
✓ Branch 0 taken 3098165177 times.
✓ Branch 1 taken 26342462 times.
3124507639 if (!is_in_scrolling_region())
477 {
478 3098165177 int pos = COMBOPOS(x, y);
479 3098165177 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
480 }
481 26342462 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
482 3124507639 }
483
484 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
485 1926 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
486 {
487 DCHECK_LAYER_ZERO_INDEX(layer);
488 1926 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
489 }
490
491 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
492 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
493 62247 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
494 {
495 DCHECK_LAYER_ZERO_INDEX(layer);
496 62247 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
497 }
498
499 25184777 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
500 {
501 DCHECK_LAYER_ZERO_INDEX(layer);
502 25184777 rpos_handle.layer = layer;
503 25184777 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
504 25184777 }
505
506 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
507 // Coordinates are clamped to the world bounds.
508 52808 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
509 {
510 DCHECK_LAYER_ZERO_INDEX(layer);
511
512 52808 x = std::clamp(x, 0, world_w - 1);
513 52808 y = std::clamp(y, 0, world_h - 1);
514
515 52808 auto maybe_ffc_handle = getFFCAt(x, y);
516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (maybe_ffc_handle)
517 return maybe_ffc_handle.value();
518
519 52808 auto rpos = COMBOPOS_REGION_B(x, y);
520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (rpos == rpos_t::None)
521 return rpos_handle_t();
522 52808 return get_rpos_handle(rpos, layer);
523 52808 }
524
525 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
526 // directly or via zscript) only last until the next area is loaded (via loadscr).
527
528 // Returns the screen containing the (x, y) world position.
529 1407668215 mapscr* get_scr_for_world_xy(int x, int y)
530 {
531 // Quick path, but should work the same without.
532
2/2
✓ Branch 0 taken 1397228855 times.
✓ Branch 1 taken 10439360 times.
1407668215 if (!is_in_scrolling_region()) return origin_scr;
533 10439360 return get_scr(get_screen_for_world_xy(x, y));
534 1407668215 }
535
536 24517848 mapscr* get_scr_for_rpos(rpos_t rpos)
537 {
538 // Quick path, but should work the same without.
539
2/2
✓ Branch 0 taken 24379902 times.
✓ Branch 1 taken 137946 times.
24517848 if (!is_in_scrolling_region()) return origin_scr;
540 137946 return get_scr(get_screen_for_rpos(rpos));
541 24517848 }
542
543 14 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
544 {
545 14 return get_scr_layer(get_screen_for_rpos(rpos), layer);
546 }
547
548 // Note: layer=0 is the base screen, 1 is the first layer, etc.
549 2016021583 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
550 {
551 DCHECK_LAYER_ZERO_INDEX(layer);
552
2/2
✓ Branch 0 taken 2005976369 times.
✓ Branch 1 taken 10045214 times.
2016021583 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
553
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 9336280 times.
10045214 return layer == 0 ?
554 708934 get_scr_for_world_xy(x, y) :
555 9336280 get_scr_layer(get_screen_for_world_xy(x, y), layer);
556 2016021583 }
557
558 1681524840 int get_region_screen_offset(int screen)
559 {
560 1681524840 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
561 }
562
563 654676699 int get_screen_for_region_index_offset(int offset)
564 {
565 654676699 int scr_dx = offset % cur_region.screen_width;
566 654676699 int scr_dy = offset / cur_region.screen_width;
567 654676699 int screen = cur_screen + scr_dx + scr_dy*16;
568 654676699 return screen;
569 }
570
571 654492862 mapscr* get_scr_for_region_index_offset(int offset)
572 {
573 654492862 int screen = get_screen_for_region_index_offset(offset);
574 654492862 return get_scr(screen);
575 }
576
577 // The screen at (map, screen) must exist.
578 1502942115 mapscr* get_scr(int map, int screen)
579 {
580 1502942115 mapscr* scr = get_scr_maybe(map, screen);
581
1/2
✓ Branch 0 taken 1502942115 times.
✗ Branch 1 not taken.
1502942115 CHECK(scr);
582 1502942115 return scr;
583 }
584
585 837682271 mapscr* get_scr(int screen)
586 {
587 837682271 return get_scr(cur_map, screen);
588 }
589
590 // Returns null if active screen does not exist.
591 1678819157 mapscr* get_scr_maybe(int map, int screen)
592 {
593 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
594
595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1678819157 times.
1678819157 if (map == cur_map)
596 {
597
2/2
✓ Branch 0 taken 1658352553 times.
✓ Branch 1 taken 20466604 times.
1678819157 if (screen == cur_screen)
598 1658352553 return origin_scr;
599
600 20466604 int index = screen*7;
601
2/2
✓ Branch 0 taken 20455512 times.
✓ Branch 1 taken 11092 times.
20466604 if (temporary_screens[index])
602 20455512 return temporary_screens[index];
603
604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11092 times.
11092 if (screen == home_screen)
605 return special_warp_return_scr;
606 11092 }
607
608
4/6
✓ Branch 0 taken 11090 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 11090 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11090 times.
11092 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
609 {
610 11090 int index = screen*7;
611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (FFCore.ScrollingScreensAll[index])
612 11090 return FFCore.ScrollingScreensAll[index];
613 }
614
615 2 return nullptr;
616 1678819157 }
617
618 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
619 6395568107 mapscr* get_scr_layer(int map, int screen, int layer)
620 {
621 DCHECK_LAYER_ZERO_INDEX(layer);
622
2/2
✓ Branch 0 taken 5733241028 times.
✓ Branch 1 taken 662327079 times.
6395568107 if (layer == 0)
623 662327079 return get_scr(map, screen);
624
625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5733241028 times.
5733241028 if (map == cur_map)
626 {
627 5733241028 int index = screen*7 + layer;
628
2/2
✓ Branch 0 taken 5733172628 times.
✓ Branch 1 taken 68400 times.
5733241028 if (temporary_screens[index])
629 5733172628 return temporary_screens[index];
630
631
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 66540 times.
68400 if (screen == home_screen)
632 1860 return &special_warp_return_scrs[layer];
633 66540 }
634
635
1/2
✓ Branch 0 taken 66540 times.
✗ Branch 1 not taken.
66540 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
636 {
637 66540 int index = screen*7 + layer;
638
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66540 times.
66540 if (FFCore.ScrollingScreensAll[index])
639 66540 return FFCore.ScrollingScreensAll[index];
640 }
641
642 NOTREACHED();
643 6395568107 }
644
645 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
646 5996297369 mapscr* get_scr_layer(int screen, int layer)
647 {
648 5996297369 return get_scr_layer(cur_map, screen, layer);
649 }
650
651 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
652 // Return nullptr if screen is not valid.
653 397196935 mapscr* get_scr_layer_valid(int screen, int layer)
654 {
655
2/2
✓ Branch 0 taken 82196698 times.
✓ Branch 1 taken 315000237 times.
397196935 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
656 82196698 return scr;
657 315000237 return nullptr;
658 397196935 }
659
660 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
661 {
662 401 int x = get_region_relative_dx(screen);
663 401 int y = get_region_relative_dy(screen);
664
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
665 71 return nullptr;
666
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
667 return nullptr;
668
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
669 return nullptr;
670
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
671 189 return nullptr;
672
673 141 screen = screen_index_direction(screen, dir);
674
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
675 return get_scr(screen);
676
677 141 return nullptr;
678 401 }
679
680 183837 ffc_handle_t get_ffc_handle(ffc_id_t id)
681 {
682 183837 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
683 183837 uint8_t i = id % MAXFFCS;
684 183837 mapscr* scr = get_scr(screen);
685 183837 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
686 183837 return {scr, screen, id, i, ffc};
687 }
688
689 34566 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
690 {
691 34566 x += get_region_relative_dx(screen) * 256;
692 34566 y += get_region_relative_dy(screen) * 176;
693 34566 return {x, y};
694 }
695
696 1049503 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
697 {
698 1049503 int x = get_region_relative_dx(screen) * 256;
699 1049503 int y = get_region_relative_dy(screen) * 176;
700 1049503 return {x, y};
701 }
702
703 11570432963 int32_t COMBOPOS(int32_t x, int32_t y)
704 {
705 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
706 11570432963 return (y & 0xF0) + (x >> 4);
707 }
708 int32_t COMBOPOS_B(int32_t x, int32_t y)
709 {
710 if(unsigned(x) >= 256 || unsigned(y) >= 176)
711 return -1;
712 return (y & 0xF0) + (x >> 4);
713 }
714 3469125376 int32_t COMBOX(int32_t pos)
715 {
716 3469125376 return pos % 16 * 16;
717 }
718 3469125376 int32_t COMBOY(int32_t pos)
719 {
720 3469125376 return pos & 0xF0;
721 }
722
723 111256644 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
724 {
725
2/2
✓ Branch 0 taken 84098708 times.
✓ Branch 1 taken 27157936 times.
111256644 if (!is_in_scrolling_region())
726 84098708 return (rpos_t) COMBOPOS(x, y);
727
728 DCHECK(is_in_world_bounds(x, y));
729 27157936 int scr_dx = x / (16*16);
730 27157936 int scr_dy = y / (11*16);
731 27157936 int pos = COMBOPOS(x%256, y%176);
732 27157936 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
733 111256644 }
734 6434699079 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
735 {
736
2/2
✓ Branch 0 taken 1400968 times.
✓ Branch 1 taken 6433298111 times.
6434699079 if (!is_in_world_bounds(x, y))
737 1400968 return rpos_t::None;
738
739 6433298111 int scr_dx = x / (16*16);
740 6433298111 int scr_dy = y / (11*16);
741 6433298111 int pos = COMBOPOS(x%256, y%176);
742 6433298111 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
743 6434699079 }
744 26541757 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
745 {
746 26541757 int scr_index = static_cast<int32_t>(rpos) / 176;
747 26541757 int scr_dx = scr_index % cur_region.screen_width;
748 26541757 int scr_dy = scr_index / cur_region.screen_width;
749 26541757 int pos = RPOS_TO_POS(rpos);
750 26541757 int x = scr_dx*16*16 + COMBOX(pos);
751 26541757 int y = scr_dy*11*16 + COMBOY(pos);
752 26541757 return {x, y};
753 }
754 60396 int32_t COMBOX_REGION(rpos_t rpos)
755 {
756 60396 auto [x, y] = COMBOXY_REGION(rpos);
757 60396 return x;
758 }
759 12225 int32_t COMBOY_REGION(rpos_t rpos)
760 {
761 12225 auto [x, y] = COMBOXY_REGION(rpos);
762 12225 return y;
763 }
764
765 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
766 {
767 DCHECK(is_in_world_bounds(x, y));
768
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
769 70177 return (rpos_t)(x + y * 16);
770
771 int scr_dx = x / 16;
772 int scr_dy = y / 11;
773 x %= 16;
774 y %= 11;
775 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
776 70177 }
777 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
778 {
779 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
780 70632 int scr_dx = scr_index % cur_region.screen_width;
781 70632 int scr_dy = scr_index / cur_region.screen_width;
782 70632 int pos = RPOS_TO_POS(rpos);
783 70632 int x = scr_dx*16 + pos%16;
784 70632 int y = scr_dy*11 + pos/16;
785 70632 return {x, y};
786 }
787
788 88520299 int32_t mapind(int32_t map, int32_t scr)
789 {
790 88520299 return map * MAPSCRSNORMAL + scr;
791 }
792
793 FONT *get_zc_font(int index);
794
795 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
796 extern movingblock mblock2; //mblock[4]?
797 extern portal mirror_portal;
798
799 void Z_message_d(const char *format,...)
800 {
801 #ifdef _DEBUG
802 char buf[512];
803 va_list ap;
804 va_start(ap, format);
805 vsprintf(buf, format, ap);
806 va_end(ap);
807
808 al_trace("%s",buf);
809 #else
810 format=format;
811 #endif
812 }
813
814
815
816 bool checktrigger=false;
817
818 void debugging_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
819 {
820 //reference/optimization: the start of the unused drawing command index can now be queried. -Gleeok
821 int32_t index = script_drawing_commands.GetNext();
822
823 if(index < 0)
824 return;
825
826 int32_t *sdci = &script_drawing_commands[index][0];
827
828 sdci[0] = RECTR;
829 sdci[1] = 30000;
830 sdci[2] = x1*10000;
831 sdci[3] = y1*10000;
832 sdci[4] = x2*10000;
833 sdci[5] = y2*10000;
834 sdci[6] = 10000;
835 sdci[7] = 10000;
836 sdci[8] = 0;
837 sdci[9] = 0;
838 sdci[10] = 0;
839 sdci[11] = 10000;
840 sdci[12] = 1280000;
841 }
842
843 void clear_dmap(word i)
844 {
845 DMaps[i].clear();
846 }
847
848 void clear_dmaps()
849 {
850 for(int32_t i=0; i<MAXDMAPS; i++)
851 {
852 clear_dmap(i);
853 }
854 }
855
856 223664462 int32_t isdungeon(int32_t dmap, int32_t screen)
857 {
858
2/2
✓ Branch 0 taken 223618782 times.
✓ Branch 1 taken 45680 times.
223664462 if (dmap < 0) dmap = cur_dmap;
859
860 // dungeons can have any dlevel above 0
861
2/2
✓ Branch 0 taken 122415017 times.
✓ Branch 1 taken 101249445 times.
223664462 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
862 {
863
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101239484 times.
101249445 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
864 9961 return 0;
865
866 101239484 return 1;
867 }
868
869 // dlevels that aren't dungeons are caves
870
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 122378190 times.
122415017 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
871 36827 return 1;
872
873 122378190 return 0;
874 223664462 }
875
876 39966139 int32_t isdungeon(int32_t screen)
877 {
878 39966139 return isdungeon(cur_dmap, screen);
879 }
880
881 183571384 int32_t isdungeon()
882 {
883 183571384 return isdungeon(cur_dmap, Hero.current_screen);
884 }
885
886 88933 bool canPermSecret(int32_t dmap, int32_t screen)
887 {
888
2/2
✓ Branch 0 taken 13910 times.
✓ Branch 1 taken 75023 times.
88933 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
889 }
890
891 1149354577 int32_t MAPCOMBO(int32_t x, int32_t y)
892 {
893 1149354577 x = vbound(x, 0, world_w-1);
894 1149354577 y = vbound(y, 0, world_h-1);
895 1149354577 int pos = COMBOPOS(x%256, y%176);
896 1149354577 mapscr* scr = get_scr_for_world_xy(x, y);
897 1149354577 return scr->data[pos];
898 }
899
900 //specific layers 1 to 6
901 1416339686 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
902 {
903 DCHECK(layer >= 1 && layer <= 6);
904
3/4
✓ Branch 0 taken 1396645792 times.
✓ Branch 1 taken 19693894 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1396645792 times.
1416339686 if (!is_in_world_bounds(x, y) || layer <= 0)
905 19693894 return 0;
906
907 1396645792 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
908
2/2
✓ Branch 0 taken 401306312 times.
✓ Branch 1 taken 995339480 times.
1396645792 if (!m->is_valid())
909 995339480 return 0;
910
911 401306312 int pos = COMBOPOS(x%256, y%176);
912 401306312 return m->data[pos];
913 1416339686 }
914
915 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
916 {
917 DCHECK(layer >= 1 && layer <= 6);
918 if (!is_in_world_bounds(x, y) || layer <= 0)
919 return 0;
920
921 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
922 if (!m->is_valid())
923 return 0;
924
925 int pos = COMBOPOS(x%256, y%176);
926 return m->cset[pos];
927 }
928
929 189308 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
930 {
931 DCHECK(layer >= 1 && layer <= 6);
932
2/4
✓ Branch 0 taken 189308 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189308 times.
189308 if (!is_in_world_bounds(x, y) || layer <= 0)
933 return 0;
934
935 189308 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
936
2/2
✓ Branch 0 taken 163782 times.
✓ Branch 1 taken 25526 times.
189308 if (!m->is_valid())
937 25526 return 0;
938
939 163782 int pos = COMBOPOS(x%256, y%176);
940 163782 return m->sflag[pos];
941 189308 }
942
943 6281 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
944 {
945 DCHECK(layer >= 1 && layer <= 6);
946
2/4
✓ Branch 0 taken 6281 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6281 times.
6281 if (!is_in_world_bounds(x, y) || layer <= 0)
947 return 0;
948
949 6281 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
950
2/2
✓ Branch 0 taken 5926 times.
✓ Branch 1 taken 355 times.
6281 if (!m->is_valid())
951 355 return 0;
952
953 5926 int pos = COMBOPOS(x%256, y%176);
954 5926 return combobuf[m->data[pos]].type;
955 6281 }
956
957 189308 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
958 {
959 DCHECK(layer >= 1 && layer <= 6);
960
2/4
✓ Branch 0 taken 189308 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189308 times.
189308 if (!is_in_world_bounds(x, y) || layer <= 0)
961 return 0;
962
963 189308 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
964
2/2
✓ Branch 0 taken 163782 times.
✓ Branch 1 taken 25526 times.
189308 if (!m->is_valid())
965 25526 return 0;
966
967 163782 int pos = COMBOPOS(x%256, y%176);
968 163782 return combobuf[m->data[pos]].flag;
969 189308 }
970
971
972 // True if the FFC covers x, y and is not ethereal or a changer.
973 2419735192 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
974 {
975
2/2
✓ Branch 0 taken 746713622 times.
✓ Branch 1 taken 1673021570 times.
2419735192 if (ffc_handle.data()<=0)
976 746713622 return false;
977
978
2/2
✓ Branch 0 taken 293414542 times.
✓ Branch 1 taken 1379607028 times.
1673021570 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
979 293414542 return false;
980
981 1379607028 int32_t fx=ffc_handle.ffc->x.getInt();
982
4/4
✓ Branch 0 taken 951721526 times.
✓ Branch 1 taken 427885502 times.
✓ Branch 2 taken 844858932 times.
✓ Branch 3 taken 106862594 times.
1379607028 if(x<fx || x>fx+(ffc_handle.scr->ffEffectWidth(ffc_handle.i)-1)) // FFC sizes are weird.
983 1272744434 return false;
984
985 106862594 int32_t fy=ffc_handle.ffc->y.getInt();
986
4/4
✓ Branch 0 taken 77552449 times.
✓ Branch 1 taken 29310145 times.
✓ Branch 2 taken 58355690 times.
✓ Branch 3 taken 19196759 times.
106862594 if(y<fy || y>fy+(ffc_handle.scr->ffEffectHeight(ffc_handle.i)-1))
987 87665835 return false;
988
989 19196759 return true;
990 2419735192 }
991
992 785490411 int32_t MAPFFCOMBO(int32_t x,int32_t y)
993 {
994
2/2
✓ Branch 0 taken 11603791 times.
✓ Branch 1 taken 773886620 times.
785490411 if (auto ffc_handle = getFFCAt(x, y))
995 11603791 return ffc_handle->data();
996 773886620 return 0;
997 785490411 }
998
999 207232 int32_t MAPCSET(int32_t x, int32_t y)
1000 {
1001
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
1002 return 0;
1003 207232 mapscr* scr = get_scr_for_world_xy(x, y);
1004 207232 int pos = COMBOPOS(x%256, y%176);
1005 207232 return scr->cset[pos];
1006 207232 }
1007
1008 73741712 int32_t MAPFLAG(int32_t x, int32_t y)
1009 {
1010
2/2
✓ Branch 0 taken 28140 times.
✓ Branch 1 taken 73713572 times.
73741712 if (!is_in_world_bounds(x, y))
1011 28140 return 0;
1012 73713572 mapscr* scr = get_scr_for_world_xy(x, y);
1013 73713572 int pos = COMBOPOS(x%256, y%176);
1014 73713572 return scr->sflag[pos];
1015 73741712 }
1016
1017 84604644 int32_t COMBOTYPE(int32_t x,int32_t y)
1018 {
1019 84604644 int32_t b=1;
1020
2/2
✓ Branch 0 taken 54646127 times.
✓ Branch 1 taken 29958517 times.
84604644 if(x&8) b<<=2;
1021
2/2
✓ Branch 0 taken 50204899 times.
✓ Branch 1 taken 34399745 times.
84604644 if(y&8) b<<=1;
1022
1023
2/2
✓ Branch 0 taken 169202250 times.
✓ Branch 1 taken 84597345 times.
253799595 for (int32_t i = 0; i <= 1; ++i)
1024 {
1025
2/2
✓ Branch 0 taken 158746666 times.
✓ Branch 1 taken 10455584 times.
169202250 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1026 {
1027
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 158746666 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
158746666 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1028 158746666 }
1029 else
1030 {
1031
4/4
✓ Branch 0 taken 10451 times.
✓ Branch 1 taken 10445133 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 7299 times.
10455584 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1032 }
1033 169194951 }
1034
1035 84597345 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1036
5/6
✓ Branch 0 taken 2449182 times.
✓ Branch 1 taken 82148163 times.
✓ Branch 2 taken 1909096 times.
✓ Branch 3 taken 540086 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1909096 times.
84597345 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1037 {
1038
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909096 times.
1909096 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1039
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909096 times.
1909096 if(cmb.usrflags&cflag3) return cNONE;
1040 1909096 }
1041 84597345 return cmb.type;
1042 84604644 }
1043
1044 49597998 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1045 {
1046 49597998 return combobuf[MAPFFCOMBO(x,y)].type;
1047 }
1048
1049 4963740 int32_t FFORCOMBO(int32_t x, int32_t y)
1050 {
1051
2/2
✓ Branch 0 taken 58516 times.
✓ Branch 1 taken 4905224 times.
4963740 if (auto ffc_handle = getFFCAt(x, y))
1052 58516 return ffc_handle->data();
1053
1054 4905224 return MAPCOMBO(x,y);
1055 4963740 }
1056
1057 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1058 {
1059 for (int32_t i = 0; i <= 1; ++i)
1060 {
1061 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1062 {
1063 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1064 }
1065 else
1066 {
1067 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1068 }
1069 }
1070 int32_t b=1;
1071
1072 if(x&8) b<<=2;
1073
1074 if(y&8) b<<=1;
1075 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1076 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1077 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1078 return cmb.type;
1079 }
1080
1081 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1082 {
1083 if (auto ffc_handle = getFFCAt(x, y))
1084 return ffc_handle->data();
1085
1086 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1087 }
1088
1089 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1090 {
1091 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1092 }
1093
1094 70224724 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1095 {
1096
2/2
✓ Branch 0 taken 27852 times.
✓ Branch 1 taken 70196872 times.
70224724 if (!is_in_world_bounds(x, y))
1097 27852 return 0;
1098
1099 70196872 mapscr* scr = get_scr_for_world_xy(x, y);
1100 70196872 int pos = COMBOPOS(x%256, y%176);
1101 70196872 return combobuf[scr->data[pos]].flag;
1102 70224724 }
1103
1104 57001369 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1105 {
1106
2/2
✓ Branch 0 taken 746177 times.
✓ Branch 1 taken 56255192 times.
57001369 if (auto ffc_handle = getFFCAt(x, y))
1107 746177 return ffc_handle->cflag();
1108
1109 56255192 return 0;
1110 57001369 }
1111
1112 1165788911 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1113 {
1114 2593852737 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1115 1428063826 return ffcIsAt(ffc_handle, x, y);
1116 });
1117 }
1118
1119 3044 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1120 {
1121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3044 times.
3044 if (!rpos_handle.scr->is_valid()) return 0;
1122 3044 return rpos_handle.data();
1123 3044 }
1124
1125 2709134276 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1126 {
1127 DCHECK_LAYER_NEG1_INDEX(layer);
1128
2/2
✓ Branch 0 taken 21695962 times.
✓ Branch 1 taken 2687438314 times.
2709134276 if (!is_in_world_bounds(x, y)) return 0;
1129
2/2
✓ Branch 0 taken 2615639313 times.
✓ Branch 1 taken 71799001 times.
2687438314 if (layer == -1) return MAPCOMBO(x, y);
1130
1131 2615639313 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1132
2/2
✓ Branch 0 taken 1771818916 times.
✓ Branch 1 taken 843820397 times.
2615639313 if (!rpos_handle.scr->is_valid()) return 0;
1133
1134 843820397 return rpos_handle.data();
1135 2709134276 }
1136
1137 17564063 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1138 {
1139 17564063 auto cid = handle.data();
1140 17564063 auto* cmb = &handle.combo();
1141 17564063 bool done = false;
1142 17564063 std::set<int32_t> visited;
1143
2/2
✓ Branch 0 taken 17564063 times.
✓ Branch 1 taken 17564063 times.
35128126 while(!done)
1144 {
1145
2/4
✓ Branch 0 taken 17564063 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17564063 times.
17564063 if(visited.contains(cid))
1146 {
1147 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1148 break; // prevent infinite loop
1149 }
1150
1/2
✓ Branch 0 taken 17564063 times.
✗ Branch 1 not taken.
17564063 visited.insert(cid);
1151
1152 17564063 done = true; // don't loop again unless something changes
1153
1/2
✓ Branch 0 taken 17564063 times.
✗ Branch 1 not taken.
18440787 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
1154 876724 return trig.trigger_flags.get(TRIGFLAG_SCREENLOAD);
1155 });
1156
2/4
✓ Branch 0 taken 17564063 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17564063 times.
17564063 if(handle.data() != cid)
1157 {
1158 cid = handle.data();
1159 cmb = &handle.combo();
1160 done = false; // loop again for the new combo
1161 }
1162 }
1163 17564063 }
1164 51231 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1165 {
1166 51231 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1167 51231 }
1168 34821 void handle_region_load_trigger()
1169 {
1170
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 34669 times.
34821 if (is_in_scrolling_region())
1171 {
1172
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1173 {
1174
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1175 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1176 19456 }
1177 152 }
1178 34669 else handle_screen_load_trigger(create_screen_handles_one(get_scr(Hero.current_screen)));
1179 34821 }
1180
1181 15262 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1182 {
1183 15262 auto screen_handles = create_screen_handles_one(&scr);
1184
1185
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 14723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15262 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1186 {
1187 539 reveal_hidden_stairs(&scr, screen, false);
1188 539 bool do_layers = false;
1189 539 bool from_active_screen = false;
1190 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1191 539 }
1192
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if (flags & mLIGHTBEAM)
1193 {
1194 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1195 if (rpos_handle.ctype() == cLIGHTTARGET)
1196 {
1197 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1198 rpos_handle.increment_data();
1199 }
1200 });
1201 }
1202
1203 15262 int lvl = DMaps[cur_dmap].level;
1204 15262 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1205 15262 toggle_gswitches_load(screen_handles);
1206
1207
2/2
✓ Branch 0 taken 15170 times.
✓ Branch 1 taken 92 times.
15262 if(flags&mLOCKBLOCK) // if special stuff done before
1208 {
1209 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1210 92 }
1211
1212
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1213 {
1214 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1215 }
1216
1217
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1218 {
1219 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1220 }
1221
1222
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1223 {
1224 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1225 }
1226
1227
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSCHEST) // if special stuff done before
1228 {
1229 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1230 }
1231
1232
1233 15262 int mi = mapind(map, screen);
1234 15262 clear_xdoors_mi(screen_handles, mi);
1235 15262 clear_xstatecombos_mi(screen_handles, mi);
1236
1237 15262 handle_screen_load_trigger(screen_handles);
1238 15262 }
1239
1240 40981 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1241 {
1242
2/4
✓ Branch 0 taken 40981 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40981 times.
40981 if (map < 0 || screen < 0)
1243 return std::nullopt;
1244
1245 40981 const mapscr* source = get_canonical_scr(map, screen);
1246
2/2
✓ Branch 0 taken 39256 times.
✓ Branch 1 taken 1725 times.
40981 if (!source->is_valid())
1247 1725 return std::nullopt;
1248
1249
2/2
✓ Branch 0 taken 7936 times.
✓ Branch 1 taken 31320 times.
39256 if (layer >= 0)
1250 {
1251
2/2
✓ Branch 0 taken 23994 times.
✓ Branch 1 taken 7326 times.
31320 if (source->layermap[layer] <= 0)
1252 23994 return std::nullopt;
1253
1254 7326 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1255
1/2
✓ Branch 0 taken 7326 times.
✗ Branch 1 not taken.
7326 if (!source->is_valid())
1256 return std::nullopt;
1257 7326 }
1258
1259
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1260 15262 mapscr scr = *source;
1261
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1262
1263
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 return scr;
1264 40981 }
1265
1266 14990 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1267 {
1268
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if (map < 0 || screen < 0) return 0;
1269
1270
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if(pos>175 || pos < 0)
1271 return 0;
1272
1273 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1274 // `apply_state_changes_to_screen` checks).
1275
4/5
✓ Branch 0 taken 4736 times.
✓ Branch 1 taken 10254 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4736 times.
✓ Branch 4 taken 10254 times.
19726 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1276 4736 return s->data[pos];
1277
1278 10254 return 0;
1279 14990 }
1280
1281 // Read from the current temporary screens or, if (map, screen) is not loaded,
1282 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1283 138002308 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1284 {
1285 DCHECK_LAYER_NEG1_INDEX(layer);
1286 DCHECK(map >= 0 && screen >= 0);
1287
1288
2/2
✓ Branch 0 taken 137987318 times.
✓ Branch 1 taken 14990 times.
138002308 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1289
1290 // Screen is not in the current region, so we have to load and trigger some secrets.
1291 14990 int pos = COMBOPOS(x, y);
1292 14990 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1293 138002308 }
1294
1295 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1296 {
1297 DCHECK_LAYER_NEG1_INDEX(layer);
1298 DCHECK(map >= 0 && screen >= 0);
1299 DCHECK(is_valid_rpos(rpos));
1300
1301 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1302
1303 // Screen is not currently loaded, so we have to load and trigger some secrets.
1304 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1305 }
1306
1307 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1308 {
1309 DCHECK_LAYER_NEG1_INDEX(layer);
1310 if (!is_in_world_bounds(x, y))
1311 return 0;
1312 if (layer == -1) return MAPCSET(x, y);
1313
1314 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1315 if (!rpos_handle.scr->is_valid()) return 0;
1316
1317 return rpos_handle.cset();
1318 }
1319
1320 99191052 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1321 {
1322 DCHECK_LAYER_NEG1_INDEX(layer);
1323
3/4
✓ Branch 0 taken 2164466 times.
✓ Branch 1 taken 97026586 times.
✓ Branch 2 taken 2164466 times.
✗ Branch 3 not taken.
99191052 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1324 return 0;
1325
2/2
✓ Branch 0 taken 81545221 times.
✓ Branch 1 taken 17645831 times.
99191052 if (layer == -1) return MAPFLAG(x, y);
1326
1327 81545221 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1328
2/2
✓ Branch 0 taken 62697629 times.
✓ Branch 1 taken 18847592 times.
81545221 if (!rpos_handle.scr->is_valid()) return 0;
1329
1330 18847592 return rpos_handle.sflag();
1331 99191052 }
1332
1333 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1334 {
1335 if(layer < 1)
1336 {
1337 for (int32_t i = layer+1; i <= 1; ++i)
1338 {
1339 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1340 {
1341 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1342 }
1343 else
1344 {
1345 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1346 }
1347 }
1348 }
1349 if(layer==-1) return COMBOTYPE(x,y);
1350
1351 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1352 if (!rpos_handle.scr->is_valid()) return 0;
1353
1354 return rpos_handle.ctype();
1355 }
1356
1357 // Returns the flag for the combo at the given position.
1358 // This is also known as an "inherent flag".
1359 97414280 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1360 {
1361 DCHECK_LAYER_NEG1_INDEX(layer);
1362
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 97413992 times.
97414280 if (!is_in_world_bounds(x, y))
1363 288 return 0;
1364
2/2
✓ Branch 0 taken 81486634 times.
✓ Branch 1 taken 15927358 times.
97413992 if (layer == -1) return MAPCOMBOFLAG(x, y);
1365
1366 81486634 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1367
2/2
✓ Branch 0 taken 62716507 times.
✓ Branch 1 taken 18770127 times.
81486634 if (!rpos_handle.scr->is_valid()) return 0;
1368
1369 18770127 return rpos_handle.cflag();
1370 97414280 }
1371
1372 11686167 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1373 {
1374 DCHECK_LAYER_ZERO_INDEX(layer);
1375 11686167 auto rpos_handle = get_rpos_handle(rpos, layer);
1376
2/2
✓ Branch 0 taken 4465414 times.
✓ Branch 1 taken 7220753 times.
11686167 if (!rpos_handle.scr->is_valid()) return false;
1377
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 7216188 times.
7220753 if (rpos_handle.sflag() == flag) return true;
1378
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 7178483 times.
7216188 if (rpos_handle.cflag() == flag) return true;
1379 7178483 return false;
1380 11686167 }
1381
1382 1705537 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1383 {
1384 DCHECK(is_valid_rpos(rpos));
1385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1705537 times.
1705537 if (rpos > region_max_rpos) return false;
1386
1387
2/2
✓ Branch 0 taken 11686167 times.
✓ Branch 1 taken 1663267 times.
13349434 for(auto q = 0; q < 7; ++q)
1388 {
1389
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11643897 times.
11686167 if(HASFLAG(flag, q, rpos))
1390 42270 return true;
1391 11643897 }
1392 1663267 return false;
1393 1705537 }
1394
1395 const char *screenstate_string[32] =
1396 {
1397 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "Some Enemies Never Return",
1398 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1399 "Boss Locked Chests", "Secrets", "Visited", "Light Beams",
1400 "All Enemies Don't Return", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1401 "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1402 };
1403
1404 34860 void eventlog_mapflags()
1405 {
1406 34860 std::ostringstream oss;
1407
1408 34860 int mi = mapind(cur_map, home_screen);
1409
1/2
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
34860 dword g = game->maps[mi];
1410
1411
2/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34860 times.
✗ Branch 3 not taken.
34860 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1412
2/2
✓ Branch 0 taken 14514 times.
✓ Branch 1 taken 20346 times.
34860 if(g) // Main States
1413 {
1414 static const int order[] =
1415 {
1416 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1417 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1418 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1419 mNEVERRET, mTMPNORET, mLIGHTBEAM, mNO_ENEMIES_RETURN
1420 };
1421
1422
1/2
✓ Branch 0 taken 14514 times.
✗ Branch 1 not taken.
14514 oss << " [";
1423 14514 bool comma = false;
1424
2/2
✓ Branch 0 taken 14514 times.
✓ Branch 1 taken 232224 times.
246738 for(int fl : order)
1425 {
1426
2/2
✓ Branch 0 taken 8979 times.
✓ Branch 1 taken 223245 times.
232224 if(!(g&fl))
1427 223245 continue;
1428 8979 byte ind = byte(log2(double(fl)));
1429
2/2
✓ Branch 0 taken 1922 times.
✓ Branch 1 taken 7057 times.
8979 if(comma)
1430
1/2
✓ Branch 0 taken 1922 times.
✗ Branch 1 not taken.
1922 oss << ", ";
1431
1/2
✓ Branch 0 taken 8979 times.
✗ Branch 1 not taken.
8979 oss << screenstate_string[ind];
1432 8979 comma = true;
1433 }
1434
1/2
✓ Branch 0 taken 14514 times.
✗ Branch 1 not taken.
14514 oss << "]";
1435 14514 }
1436
3/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 34822 times.
34860 if(game->xstates[mi]) // ExStates
1437 {
1438
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 oss << " Ex[";
1439 38 bool comma = false;
1440
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 1216 times.
1254 for(byte fl = 0; fl < 32; ++fl)
1441 {
1442
3/4
✓ Branch 0 taken 1216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 1172 times.
1216 if(game->xstates[mi] & (1<<fl))
1443 {
1444
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 38 times.
44 if(comma)
1445
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 oss << ", ";
1446
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 oss << int(fl);
1447 44 comma = true;
1448 44 }
1449 1216 }
1450
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 oss << "]";
1451 38 }
1452 { // ExDoors
1453
2/2
✓ Branch 0 taken 34860 times.
✓ Branch 1 taken 139440 times.
174300 for(int q = 0; q < 4; ++q)
1454 {
1455 139440 bool comma = false;
1456
3/4
✓ Branch 0 taken 139440 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 139438 times.
✓ Branch 3 taken 2 times.
139440 if(auto v = game->xdoors[mi][q])
1457 {
1458
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(comma)
1459 oss << ",";
1460
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else oss << " ExDoor";
1461
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 oss << "[" << dirstr[q];
1462
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 for(int fl = 0; fl < 8; ++fl)
1463
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
19 if(v & (1<<fl))
1464
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 oss << " " << int(fl);
1465
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 oss << "]";
1466 2 comma = true;
1467 2 }
1468 139440 }
1469 }
1470
2/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 34860 times.
34860 Z_eventlog("%s\n", oss.str().c_str());
1471 34860 }
1472
1473 // set specific flag
1474 5616 void setmapflag(mapscr* scr, uint32_t flag)
1475 {
1476
2/2
✓ Branch 0 taken 5603 times.
✓ Branch 1 taken 13 times.
5616 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1477 5616 int mi = mapind(cur_map, scr->screen);
1478 5616 setmapflag_mi(scr, mi, flag);
1479 5616 }
1480 57 void setmapflag_homescr(uint32_t flag)
1481 {
1482 57 int mi = mapind(cur_map, home_screen);
1483 57 setmapflag_mi(origin_scr, mi, flag);
1484 57 }
1485 2023 void setmapflag_mi(int32_t mi, uint32_t flag)
1486 {
1487 2023 byte cscr = mi&((1<<7)-1);
1488 2023 byte cmap = (mi>>7);
1489 2023 mapscr* scr = origin_scr;
1490
2/2
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 1189 times.
2023 if (is_in_current_region(cmap, cscr))
1491 1189 scr = get_scr(cmap, cscr);
1492
1493 2023 setmapflag_mi(scr, mi, flag);
1494 2023 }
1495
1496 8479 static void log_state_change(int map, int screen, std::string action)
1497 {
1498
6/6
✓ Branch 0 taken 1913 times.
✓ Branch 1 taken 6566 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 917 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 644 times.
8479 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1499 6918 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1500 else
1501 1561 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1502 8479 }
1503
1504 7696 void setmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag)
1505 {
1506 7696 byte cscr = mi&((1<<7)-1);
1507 7696 byte cmap = (mi>>7);
1508
1509 7696 double temp=log2((double)flag);
1510
1/2
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
7696 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1511 7696 const char* replay_state_string = state_string;
1512
2/2
✓ Branch 0 taken 7176 times.
✓ Branch 1 taken 520 times.
7696 if(temp == 6) replay_state_string = "No Return";
1513
1514
3/4
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1552 times.
✓ Branch 3 taken 6144 times.
7696 if (replay_is_active() && !(game->maps[mi] & flag))
1515
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, replay_state_string));
1516 7696 game->maps[mi] |= flag;
1517
1/2
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
7696 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1518
1519
2/2
✓ Branch 0 taken 2507 times.
✓ Branch 1 taken 5189 times.
7696 if((scr->nocarry&flag)!=flag)
1520 {
1521 5189 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1522 5189 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1523
1524 5189 std::vector<int32_t> done;
1525
2/2
✓ Branch 0 taken 5094 times.
✓ Branch 1 taken 95 times.
5189 bool looped = (nmap==cmap+1 && nscr==cscr);
1526
1527
6/6
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 5147 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 364 times.
✓ Branch 4 taken 364 times.
✓ Branch 5 taken 5189 times.
5553 while((nmap!=0) && !looped && !(nscr>=128))
1528 {
1529
3/4
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 171 times.
✓ Branch 3 taken 193 times.
364 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1530 {
1531
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 log_state_change(nmap, nscr, "State change carried over");
1532
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 if (replay_is_active())
1533
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, replay_state_string));
1534
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 game->maps[((nmap-1)<<7)+nscr] |= flag;
1535 193 }
1536
1537 364 cmap=nmap;
1538 364 cscr=nscr;
1539 364 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1540 364 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1541
1542
2/2
✓ Branch 0 taken 889 times.
✓ Branch 1 taken 364 times.
1253 for(auto it = done.begin(); it != done.end(); it++)
1543 {
1544
2/2
✓ Branch 0 taken 847 times.
✓ Branch 1 taken 42 times.
889 if(*it == ((nmap-1)<<7)+nscr)
1545 42 looped = true;
1546 889 }
1547
1548
1/2
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
364 done.push_back(((nmap-1)<<7)+nscr);
1549 }
1550 5189 }
1551 7696 }
1552
1553 void unsetmapflag_home(uint32_t flag, bool anyflag)
1554 {
1555 int mi = mapind(cur_map, home_screen);
1556 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1557 }
1558
1559 void unsetmapflag(mapscr* scr, uint32_t flag, bool anyflag)
1560 {
1561 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1562 int mi = mapind(cur_map, scr->screen);
1563 unsetmapflag_mi(scr, mi, flag, anyflag);
1564 }
1565
1566 471 void unsetmapflag_mi(int32_t mi, uint32_t flag, bool anyflag)
1567 {
1568 471 byte cscr = mi&((1<<7)-1);
1569 471 byte cmap = (mi>>7);
1570 471 mapscr* scr = origin_scr;
1571
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1572 11 scr = get_scr(cmap, cscr);
1573
1574 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1575 471 }
1576
1577 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag, bool anyflag)
1578 {
1579 471 byte cscr = mi&((1<<7)-1);
1580 471 byte cmap = (mi>>7);
1581
1582
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1583 460 game->maps[mi] &= ~flag;
1584
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1585 {
1586 if(!(scr->flags4&fNOITEMRESET))
1587 game->maps[mi] &= ~flag;
1588 }
1589 11 else game->maps[mi] &= ~flag;
1590
1591 471 double temp=log2((double)flag);
1592
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1593
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1594
1595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 471 times.
471 if((scr->nocarry&flag)!=flag)
1596 {
1597 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1598 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1599
1600 471 std::vector<int32_t> done;
1601
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1602
1603
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1604 {
1605
3/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 72 times.
84 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1606 {
1607
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1608
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1609 72 }
1610
1611 84 cmap=nmap;
1612 84 cscr=nscr;
1613 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1614 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1615
1616
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 546 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1617 {
1618
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1619 6 looped = true;
1620 546 }
1621
1622
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1623 }
1624 471 }
1625 471 }
1626
1627 50185411 bool getmapflag(int32_t screen, uint32_t flag)
1628 {
1629
2/2
✓ Branch 0 taken 1345925 times.
✓ Branch 1 taken 48839486 times.
50185411 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1630 50185411 return (game->maps[mi] & flag) != 0;
1631 }
1632 6231482 bool getmapflag(mapscr* scr, uint32_t flag)
1633 {
1634 6231482 return getmapflag(scr->screen, flag);
1635 }
1636
1637 40 void setxmapflag(int32_t screen, uint32_t flag)
1638 {
1639
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1640 40 setxmapflag_mi(mi, flag);
1641 40 }
1642 42 void setxmapflag_mi(int32_t mi, uint32_t flag)
1643 {
1644
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if(game->xstates[mi] & flag) return;
1645 42 byte cscr = mi&((1<<7)-1);
1646 42 byte cmap = (mi>>7);
1647
1648 42 byte temp=(byte)log2((double)flag);
1649
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1650
1651 42 game->xstates[mi] |= flag;
1652
1653 42 mapscr* scr = origin_scr;
1654
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if (is_in_current_region(cmap, cscr))
1655 42 scr = get_scr(cmap, cscr);
1656
1657
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 if((scr->exstate_carry&flag)==flag)
1658 {
1659 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1660 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1661
1662 std::vector<int32_t> done;
1663 bool looped = (nmap==cmap+1 && nscr==cscr);
1664
1665 while((nmap!=0) && !looped && !(nscr>=128))
1666 {
1667 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1668 {
1669 log_state_change(nmap, nscr, "ExState change carried over");
1670 if (replay_is_active())
1671 replay_step_comment(fmt::format("map {} scr {} exstate {} carry", nmap, nscr, temp));
1672 game->xstates[((nmap-1)<<7)+nscr] |= flag;
1673 }
1674
1675 cmap=nmap;
1676 cscr=nscr;
1677 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1678 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1679
1680 for(auto it = done.begin(); it != done.end(); it++)
1681 {
1682 if(*it == ((nmap-1)<<7)+nscr)
1683 looped = true;
1684 }
1685
1686 done.push_back(((nmap-1)<<7)+nscr);
1687 }
1688 }
1689 42 }
1690 2 void unsetxmapflag(int32_t screen, uint32_t flag)
1691 {
1692
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1693 2 unsetxmapflag_mi(mi, flag);
1694 2 }
1695 2 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1696 {
1697
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!(game->xstates[mi] & flag)) return;
1698 1 byte cscr = mi&((1<<7)-1);
1699 1 byte cmap = (mi>>7);
1700 1 byte temp=(byte)log2((double)flag);
1701
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1702 1 game->xstates[mi] &= ~flag;
1703
1704 1 mapscr* scr = origin_scr;
1705
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (is_in_current_region(cmap, cscr))
1706 1 scr = get_scr(cmap, cscr);
1707
1708
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((scr->exstate_carry&flag)==flag)
1709 {
1710 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1711 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1712
1713 std::vector<int32_t> done;
1714 bool looped = (nmap==cmap+1 && nscr==cscr);
1715
1716 while((nmap!=0) && !looped && !(nscr>=128))
1717 {
1718 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1719 {
1720 log_state_change(nmap, nscr, "ExState change carried over");
1721 game->xstates[((nmap-1)<<7)+nscr] &= ~flag;
1722 }
1723
1724 cmap=nmap;
1725 cscr=nscr;
1726 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1727 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1728
1729 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1730 {
1731 if(*it == ((nmap-1)<<7)+nscr)
1732 looped = true;
1733 }
1734
1735 done.push_back(((nmap-1)<<7)+nscr);
1736 }
1737 }
1738 2 }
1739 64 bool getxmapflag(int32_t screen, uint32_t flag)
1740 {
1741
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
64 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1742 64 return getxmapflag_mi(mi, flag);
1743 }
1744 471570734 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1745 {
1746 471570734 return (game->xstates[mi] & flag) != 0;
1747 }
1748
1749 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1750 {
1751
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1752 return;
1753
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1754 return;
1755
1756
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1757
1758 4 int cscr = mi % MAPSCRSNORMAL;
1759 4 int cmap = mi / MAPSCRSNORMAL;
1760
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1761
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1762 else
1763 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1764 4 }
1765 471570665 bool getxdoor_mi(uint mi, uint dir, uint ind)
1766 {
1767
3/6
✓ Branch 0 taken 471570665 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 471570665 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 471570665 times.
471570665 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1768 return false;
1769 471570665 return (game->xdoors[mi][dir] & (1<<ind));
1770 471570665 }
1771 9 bool getxdoor(int32_t screen, uint dir, uint ind)
1772 {
1773 9 int mi = mapind(cur_map, screen);
1774 9 return getxdoor_mi(mi,dir,ind);
1775 }
1776
1777 401 void set_doorstate_mi(uint mi, uint dir)
1778 {
1779
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1780 return;
1781 401 setmapflag_mi(mi, mDOOR_UP << dir);
1782
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1783 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1784 401 }
1785 401 void set_doorstate(uint screen, uint dir)
1786 {
1787 401 int mi = mapind(cur_map, screen);
1788 401 set_doorstate_mi(mi, dir);
1789 401 }
1790
1791 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1792 {
1793
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1794 return;
1795 2 setxdoor_mi(mi, dir, ind, state);
1796
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1797 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1798 2 }
1799
1800 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1801 {
1802 2 int mi = mapind(cur_map, screen);
1803 2 set_xdoorstate_mi(mi, dir, ind, state);
1804 2 }
1805
1806 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1807 // returns: -1 = not a warp screen
1808 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1809 {
1810 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1811
1812
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1813 return -1;
1814
1815 57 int32_t ring=scr->catchall;
1816 57 int32_t size=QMisc.warp[ring].size;
1817
1818
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1819 return -2;
1820
1821 57 int32_t index=-1;
1822
1823
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1824
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1825 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1826 57 index=i;
1827
1828
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1829 return -3;
1830
1831 57 index = (index+dw)%size;
1832 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1833 57 }
1834
1835 14782558 void update_combo_cycling()
1836 {
1837 14782558 auto& combo_cache = combo_caches::can_cycle;
1838
1839 static int32_t newdata[176];
1840 static int32_t newcset[176];
1841 static bool initialized=false;
1842
1843 // Just a simple bit of optimization
1844
2/2
✓ Branch 0 taken 14782246 times.
✓ Branch 1 taken 312 times.
14782558 if(!initialized)
1845 {
1846
2/2
✓ Branch 0 taken 54912 times.
✓ Branch 1 taken 312 times.
55224 for(int32_t i=0; i<176; i++)
1847 {
1848 54912 newdata[i]=-1;
1849 54912 newcset[i]=-1;
1850 54912 }
1851
1852 312 initialized=true;
1853 312 }
1854
1855 14782558 std::set<uint16_t> restartanim;
1856
1857
1/2
✓ Branch 0 taken 14782558 times.
✗ Branch 1 not taken.
29954484 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1858 15171926 int screen = scr->screen;
1859 int32_t x;
1860
1861
2/2
✓ Branch 0 taken 2670258976 times.
✓ Branch 1 taken 15171926 times.
2685430902 for(int32_t i=0; i<176; i++)
1862 {
1863 2670258976 x=scr->data[i];
1864 2670258976 auto& mini_cmb = combo_cache.minis[x];
1865
2/2
✓ Branch 0 taken 3273932 times.
✓ Branch 1 taken 2666985044 times.
2670258976 if (!mini_cmb.can_cycle)
1866 2666985044 continue;
1867
1868 3273932 newcombo const& cmb = combobuf[x];
1869
1870 //time to restart
1871
4/4
✓ Branch 0 taken 902694 times.
✓ Branch 1 taken 2371238 times.
✓ Branch 2 taken 474434 times.
✓ Branch 3 taken 428260 times.
3273932 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1872 {
1873 428260 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1874
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428260 times.
428260 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1875 428260 newdata[i] = c;
1876
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428240 times.
428260 if(!(cmb.animflags & AF_CYCLENOCSET))
1877
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428240 times.
428240 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1878
1879
2/2
✓ Branch 0 taken 427216 times.
✓ Branch 1 taken 1044 times.
428260 if(combobuf[c].animflags & AF_CYCLE)
1880 {
1881 1044 restartanim.insert(c);
1882 1044 }
1883 428260 }
1884 3273932 }
1885
1886 15171926 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1887
2/2
✓ Branch 0 taken 2670258976 times.
✓ Branch 1 taken 15171926 times.
2685430902 for(int32_t i=0; i<176; i++)
1888 {
1889
2/2
✓ Branch 0 taken 428260 times.
✓ Branch 1 taken 2669830716 times.
2670258976 if(newdata[i]==-1)
1890 2669830716 continue;
1891
1892 428260 rpos_t rpos = (rpos_t)(rpos_base + i);
1893 428260 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1894 428260 screen_combo_modify_preroutine(rpos_handle);
1895 428260 scr->data[i]=newdata[i];
1896
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428240 times.
428260 if(newcset[i]>-1)
1897 428240 scr->cset[i]=newcset[i];
1898 428260 screen_combo_modify_postroutine(rpos_handle);
1899
1900 428260 newdata[i]=-1;
1901 428260 newcset[i]=-1;
1902 428260 }
1903
1904 15171926 word c = scr->numFFC();
1905
2/2
✓ Branch 0 taken 15171926 times.
✓ Branch 1 taken 453640163 times.
468812089 for(word i=0; i<c; i++)
1906 {
1907 453640163 ffcdata& ffc = scr->ffcs[i];
1908 453640163 auto& mini_cmb = combo_cache.minis[ffc.data];
1909
2/2
✓ Branch 0 taken 4173 times.
✓ Branch 1 taken 453635990 times.
453640163 if (!mini_cmb.can_cycle)
1910 453635990 continue;
1911
1912 4173 newcombo const& cmb = combobuf[ffc.data];
1913
1914 //time to restart
1915
4/4
✓ Branch 0 taken 611 times.
✓ Branch 1 taken 3562 times.
✓ Branch 2 taken 503 times.
✓ Branch 3 taken 108 times.
4173 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1916 {
1917 108 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1918
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1919 108 zc_ffc_set(ffc, c);
1920
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if(!(cmb.animflags & AF_CYCLENOCSET))
1921
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1922
1923
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 60 times.
108 if(combobuf[ffc.data].animflags & AF_CYCLE)
1924 {
1925 60 restartanim.insert(ffc.data);
1926 60 }
1927 108 }
1928 4173 }
1929
1930
2/2
✓ Branch 0 taken 8418399 times.
✓ Branch 1 taken 6753527 times.
15171926 if(get_qr(qr_CMBCYCLELAYERS))
1931 {
1932
2/2
✓ Branch 0 taken 40521162 times.
✓ Branch 1 taken 6753527 times.
47274689 for(int32_t j=1; j<=6; j++)
1933 {
1934 40521162 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1935
2/2
✓ Branch 0 taken 11603202 times.
✓ Branch 1 taken 28917960 times.
40521162 if (!layer_scr)
1936 28917960 continue;
1937
1938
2/2
✓ Branch 0 taken 2042163552 times.
✓ Branch 1 taken 11603202 times.
2053766754 for(int32_t i=0; i<176; i++)
1939 {
1940 2042163552 x=layer_scr->data[i];
1941 2042163552 auto& mini_cmb = combo_cache.minis[x];
1942
2/2
✓ Branch 0 taken 2230074 times.
✓ Branch 1 taken 2039933478 times.
2042163552 if (!mini_cmb.can_cycle)
1943 2039933478 continue;
1944
1945 2230074 newcombo const& cmb = combobuf[x];
1946
1947 //time to restart
1948
4/4
✓ Branch 0 taken 48416 times.
✓ Branch 1 taken 2181658 times.
✓ Branch 2 taken 37483 times.
✓ Branch 3 taken 10933 times.
2230074 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1949 {
1950 10933 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1951
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10933 times.
10933 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1952 10933 newdata[i] = c;
1953
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 10864 times.
10933 if(!(cmb.animflags & AF_CYCLENOCSET))
1954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10864 times.
10864 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1955 69 else newcset[i] = layer_scr->cset[i];
1956
1957
2/2
✓ Branch 0 taken 950 times.
✓ Branch 1 taken 9983 times.
10933 if(combobuf[c].animflags & AF_CYCLE)
1958 {
1959 9983 restartanim.insert(c);
1960 9983 }
1961 10933 }
1962 2230074 }
1963
1964
2/2
✓ Branch 0 taken 2042163552 times.
✓ Branch 1 taken 11603202 times.
2053766754 for (int32_t i=0; i<176; i++)
1965 {
1966
2/2
✓ Branch 0 taken 2042152619 times.
✓ Branch 1 taken 10933 times.
2042163552 if(newdata[i]!=-1)
1967 {
1968 10933 layer_scr->data[i]=newdata[i];
1969
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10933 times.
10933 if(newcset[i]>-1)
1970 10933 layer_scr->cset[i]=newcset[i];
1971 10933 newdata[i]=-1;
1972 10933 newcset[i]=-1;
1973 10933 }
1974 2042163552 }
1975 11603202 }
1976 6753527 }
1977 15171926 });
1978
1979
2/2
✓ Branch 0 taken 14782558 times.
✓ Branch 1 taken 2661 times.
14785219 for (auto i : restartanim)
1980 {
1981 2661 combobuf[i].tile = combobuf[i].o_tile;
1982 2661 combobuf[i].cur_frame=0;
1983 2661 combobuf[i].aclk = 0;
1984
1/2
✓ Branch 0 taken 2661 times.
✗ Branch 1 not taken.
2661 combo_caches::drawing.refresh(i);
1985 }
1986 14782558 }
1987
1988 1213412231 bool iswater_type(int32_t type)
1989 {
1990 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1991 1213412231 return (combo_class_buf[type].water!=0);
1992 }
1993
1994 bool iswater(int32_t combo)
1995 {
1996 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1997 }
1998 1135408 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1999 {
2000 1135408 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
2001 }
2002
2003 // (x, y) are world coordinates
2004 58774109 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
2005 {
2006
8/8
✓ Branch 0 taken 58727958 times.
✓ Branch 1 taken 46151 times.
✓ Branch 2 taken 58687626 times.
✓ Branch 3 taken 40332 times.
✓ Branch 4 taken 58620880 times.
✓ Branch 5 taken 66746 times.
✓ Branch 6 taken 59577 times.
✓ Branch 7 taken 58561303 times.
58774109 if (x<0 || x>=world_w || y<0 || y>=world_h)
2007 212806 return false;
2008
2009 58561303 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
2010 58774109 }
2011
2012 97323479 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
2013 {
2014 DCHECK_LAYER_NEG1_INDEX(layer);
2015 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
2016 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
2017
2018 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
2019
2/2
✓ Branch 0 taken 57473628 times.
✓ Branch 1 taken 39849851 times.
97323479 if (get_qr(qr_SMARTER_WATER))
2020 {
2021
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 57473628 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
57473628 if (DRIEDLAKE) return 0;
2022
5/6
✓ Branch 0 taken 19589627 times.
✓ Branch 1 taken 37884001 times.
✓ Branch 2 taken 6518567 times.
✓ Branch 3 taken 13071060 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6518567 times.
57473628 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
2023 {
2024
2/2
✓ Branch 0 taken 37866480 times.
✓ Branch 1 taken 12397710 times.
50264190 for (int32_t m = layer; m <= 1; m++)
2025 {
2026
5/6
✓ Branch 0 taken 24795420 times.
✓ Branch 1 taken 13071060 times.
✓ Branch 2 taken 12397710 times.
✓ Branch 3 taken 12397710 times.
✓ Branch 4 taken 12397710 times.
✗ Branch 5 not taken.
50264190 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
2027
1/2
✓ Branch 0 taken 12397710 times.
✗ Branch 1 not taken.
24795420 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
2028 {
2029 37866480 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
2030
2/2
✓ Branch 0 taken 37193130 times.
✓ Branch 1 taken 673350 times.
37866480 if (checkwater > 0)
2031 {
2032
2/2
✓ Branch 0 taken 673292 times.
✓ Branch 1 taken 58 times.
673350 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
2033 673350 return checkwater;
2034 }
2035 37193130 }
2036 37193130 }
2037 12397710 return 0;
2038 }
2039 else
2040 {
2041
2/2
✓ Branch 0 taken 44417241 times.
✓ Branch 1 taken 42228389 times.
86645630 for(int32_t i=(fullcheck?3:0); i>=0; i--)
2042 {
2043 44417241 int32_t tx2=((i&2)<<2)+x;
2044 44417241 int32_t ty2=((i&1)<<3)+y;
2045 44417241 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
2046 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
2047
2/2
✓ Branch 0 taken 21673 times.
✓ Branch 1 taken 44395568 times.
44417241 if (!fullcheck)
2048 {
2049 44395568 tx2 = x;
2050 44395568 ty2 = y;
2051
2/2
✓ Branch 0 taken 24924551 times.
✓ Branch 1 taken 19471017 times.
44395568 if(tx2&8) b+=2;
2052
2/2
✓ Branch 0 taken 20569499 times.
✓ Branch 1 taken 23826069 times.
44395568 if(ty2&8) b+=1;
2053 44395568 }
2054
2/2
✓ Branch 0 taken 94952381 times.
✓ Branch 1 taken 43573008 times.
138525389 for (int32_t m = layer; m <= 1; m++)
2055 {
2056 94952381 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
2057
3/6
✓ Branch 0 taken 94884826 times.
✓ Branch 1 taken 67555 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 94884826 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
94952381 if (hero && cmb.dive_under_level && (Hero.get_standing_z_state() <= -cmb.dive_under_level))
2058 continue; // dive under this layer
2059
2060
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 77216654 times.
94952381 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2061 {
2062
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17735727 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17735727 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
2063 {
2064 return 0;
2065 }
2066 17735727 }
2067 else
2068 {
2069
4/4
✓ Branch 0 taken 179102 times.
✓ Branch 1 taken 77037552 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 127950 times.
77216654 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
2070 {
2071 127950 return 0;
2072 }
2073 }
2074
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 77088704 times.
94824431 if (get_qr(qr_NO_SOLID_SWIM))
2075 {
2076
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 77037552 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 716283 times.
✓ Branch 5 taken 76321269 times.
✓ Branch 6 taken 3461 times.
✓ Branch 7 taken 712822 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3461 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
77088704 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
2077 716283 return 0;
2078 76372421 }
2079
3/6
✓ Branch 0 taken 320361 times.
✓ Branch 1 taken 93787787 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320361 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
94108148 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
2080 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
2081 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
2082 {
2083 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
2084 }
2085 94108148 }
2086
2087 131435415 auto found_ffc_not_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2088
2/2
✓ Branch 0 taken 87334542 times.
✓ Branch 1 taken 527865 times.
87862407 if (ffcIsAt(ffc_handle, tx2, ty2))
2089 {
2090 527865 auto ty = ffc_handle.ctype();
2091
4/6
✓ Branch 0 taken 527865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144225 times.
✓ Branch 3 taken 383640 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 144225 times.
527865 if(!combo_class_buf[ty].water && !(ShallowCheck && ty == cSHALLOWWATER))
2092 527865 return true;
2093 }
2094
2095 87334542 return false;
2096 87862407 });
2097
2/2
✓ Branch 0 taken 43045143 times.
✓ Branch 1 taken 527865 times.
43573008 if (found_ffc_not_water) return 0;
2098
2099
2/2
✓ Branch 0 taken 14673 times.
✓ Branch 1 taken 43030470 times.
43045143 if(!i)
2100 {
2101 128041091 auto found_ffc_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2102
1/2
✓ Branch 0 taken 85010621 times.
✗ Branch 1 not taken.
85010621 if (ffcIsAt(ffc_handle, tx2, ty2))
2103 {
2104 auto ty = ffc_handle.ctype();
2105 if(combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER))
2106 return true;
2107 }
2108
2109 85010621 return false;
2110 85010621 });
2111
1/2
✓ Branch 0 taken 43030470 times.
✗ Branch 1 not taken.
43030470 if (found_ffc_water)
2112 {
2113 if(out_handle) *out_handle = *found_ffc_water;
2114 return found_ffc_water->data();
2115 }
2116 43030470 }
2117
2118 43045143 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2119
2/2
✓ Branch 0 taken 43000649 times.
✓ Branch 1 taken 44494 times.
43045143 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2120
7/12
✓ Branch 0 taken 42720019 times.
✓ Branch 1 taken 280630 times.
✓ Branch 2 taken 10857249 times.
✓ Branch 3 taken 31862770 times.
✓ Branch 4 taken 10379065 times.
✓ Branch 5 taken 478184 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10379065 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
43000649 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2121 {
2122
2/2
✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 757587 times.
758814 if (i == 0)
2123 {
2124
2/2
✓ Branch 0 taken 757578 times.
✓ Branch 1 taken 9 times.
757587 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2125 757587 return checkcombo;
2126 }
2127 1227 }
2128 42243062 }
2129 42228389 return 0;
2130 }
2131 }
2132 else
2133 {
2134 39849851 int32_t b = 0;
2135
2/2
✓ Branch 0 taken 20636802 times.
✓ Branch 1 taken 19213049 times.
39849851 if(x&8) b+=2;
2136
2/2
✓ Branch 0 taken 15456875 times.
✓ Branch 1 taken 24392976 times.
39849851 if(y&8) b+=1;
2137
1/2
✓ Branch 0 taken 39849851 times.
✗ Branch 1 not taken.
39849851 if (get_qr(qr_NO_SOLID_SWIM))
2138 {
2139 if (combobuf[combo].walk&(1<<b))
2140 {
2141 return 0;
2142 }
2143 }
2144
1/2
✓ Branch 0 taken 39849851 times.
✗ Branch 1 not taken.
39849851 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2145
8/8
✓ Branch 0 taken 38150901 times.
✓ Branch 1 taken 1698950 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982956 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1782338 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 161691 times.
39849851 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2146 {
2147
2/2
✓ Branch 0 taken 1943999 times.
✓ Branch 1 taken 30 times.
1944029 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2148 1944029 return combo;
2149 }
2150 38146730 return 0;
2151 }
2152 97564387 }
2153
2154 326 bool isdamage_type(int32_t type)
2155 {
2156
1/2
✓ Branch 0 taken 326 times.
✗ Branch 1 not taken.
326 switch(type)
2157 {
2158 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2159 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2160 return true;
2161 }
2162 326 return false;
2163 326 }
2164
2165 2129050697 bool ispitfall_type(int32_t type)
2166 {
2167 2129050697 return combo_class_buf[type].pit != 0;
2168 }
2169
2170 2129050697 bool ispitfall(int32_t combo)
2171 {
2172 2129050697 return ispitfall_type(combobuf[combo].type);
2173 }
2174
2175 131110132 bool ispitfall(int32_t x, int32_t y)
2176 {
2177
2/2
✓ Branch 0 taken 1274013 times.
✓ Branch 1 taken 129836119 times.
131110132 if(int32_t c = MAPFFCOMBO(x,y))
2178 {
2179 1274013 return ispitfall(c) ? true : false;
2180 }
2181 129836119 int32_t c = MAPCOMBOL(2,x,y);
2182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 129836119 times.
129836119 if(ispitfall(c)) return true;
2183
2/2
✓ Branch 0 taken 122656443 times.
✓ Branch 1 taken 7179676 times.
129836119 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2184 {
2185
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122656443 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122656443 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2186 122656443 }
2187 else
2188 {
2189
3/4
✓ Branch 0 taken 2780 times.
✓ Branch 1 taken 7176896 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2780 times.
7179676 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2190 }
2191 129833339 c = MAPCOMBOL(1,x,y);
2192
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 129833315 times.
129833339 if(ispitfall(c)) return true;
2193
2194
2/2
✓ Branch 0 taken 122656443 times.
✓ Branch 1 taken 7176872 times.
129833315 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2195 {
2196
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122656443 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122656443 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2197 122656443 }
2198 else
2199 {
2200
4/4
✓ Branch 0 taken 13072 times.
✓ Branch 1 taken 7163800 times.
✓ Branch 2 taken 8777 times.
✓ Branch 3 taken 4295 times.
7176872 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2201 }
2202 129824538 c = MAPCOMBO(x,y);
2203
2/2
✓ Branch 0 taken 56973 times.
✓ Branch 1 taken 129767565 times.
129824538 if(ispitfall(c)) return true;
2204 129767565 return false;
2205 131110132 }
2206
2207 585673358 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2208 {
2209
2/2
✓ Branch 0 taken 9281019 times.
✓ Branch 1 taken 576392339 times.
585673358 if(int32_t c = MAPFFCOMBO(x,y))
2210 {
2211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9281019 times.
9281019 return ispitfall(c) ? c : 0;
2212 }
2213 576392339 int32_t c = MAPCOMBOL(2,x,y);
2214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 576392339 times.
576392339 if(ispitfall(c)) return c;
2215
2216
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 43669854 times.
576392339 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2217 {
2218
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2219 532722485 }
2220 else
2221 {
2222
3/4
✓ Branch 0 taken 35747 times.
✓ Branch 1 taken 43634107 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 35747 times.
43669854 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2223 }
2224 576356592 c = MAPCOMBOL(1,x,y);
2225
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 576356314 times.
576356592 if(ispitfall(c)) return c;
2226
2227
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 43633829 times.
576356314 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2228 {
2229
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2230 532722485 }
2231 else
2232 {
2233
4/4
✓ Branch 0 taken 144357 times.
✓ Branch 1 taken 43489472 times.
✓ Branch 2 taken 103729 times.
✓ Branch 3 taken 40628 times.
43633829 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2234 }
2235 576252585 c = MAPCOMBO(x,y);
2236
2/2
✓ Branch 0 taken 176844 times.
✓ Branch 1 taken 576075741 times.
576252585 if(ispitfall(c)) return c;
2237 576075741 return 0;
2238 585673358 }
2239 51 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2240 {
2241
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(int32_t c = MAPFFCOMBO(x,y))
2242 {
2243 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2244 }
2245 51 int32_t c = MAPCOMBOL(2,x,y);
2246
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2247
2248
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 45 times.
51 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2249 {
2250
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2251 return nullopt;
2252 6 }
2253 else
2254 {
2255
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2256 return nullopt;
2257 }
2258 51 c = MAPCOMBOL(1,x,y);
2259
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2260
2261
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 45 times.
51 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2262 {
2263
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2264 return nullopt;
2265 6 }
2266 else
2267 {
2268
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2269 return nullopt;
2270 }
2271 51 c = MAPCOMBO(x,y);
2272
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2273 return nullopt;
2274 51 }
2275 5458350 bool check_icy(newcombo const& cmb, int type)
2276 {
2277
2/2
✓ Branch 0 taken 5458185 times.
✓ Branch 1 taken 165 times.
5458350 if(cmb.type != cICY)
2278 5458185 return false;
2279
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
165 switch(type)
2280 {
2281 case ICY_BLOCK:
2282 return cmb.usrflags&cflag1;
2283 case ICY_PLAYER:
2284 165 return cmb.usrflags&cflag2;
2285 }
2286 return false;
2287 5458350 }
2288 1821974 int get_icy(int x, int y, int type)
2289 {
2290 1821974 int32_t c = MAPCOMBOL(2,x,y);
2291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1821974 times.
1821974 if(check_icy(combobuf[c], type)) return c;
2292
2293 1821974 int screen = get_screen_for_world_xy(x, y);
2294
2295 1821974 mapscr* scr = get_scr_layer_valid(screen, 2);
2296
2/2
✓ Branch 0 taken 4618 times.
✓ Branch 1 taken 1817356 times.
1821974 if (scr)
2297 {
2298
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 1816840 times.
1817356 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2299 {
2300
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2301 516 }
2302 else
2303 {
2304
3/4
✓ Branch 0 taken 3048 times.
✓ Branch 1 taken 1813792 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3048 times.
1816840 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2305 }
2306 1814308 }
2307 1818926 c = MAPCOMBOL(1,x,y);
2308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1818926 times.
1818926 if(check_icy(combobuf[c], type)) return c;
2309
2310 1818926 scr = get_scr_layer_valid(screen, 1);
2311
2/2
✓ Branch 0 taken 12997 times.
✓ Branch 1 taken 1805929 times.
1818926 if (scr)
2312 {
2313
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 1803995 times.
1805929 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2314 {
2315
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2316 1934 }
2317 else
2318 {
2319
3/4
✓ Branch 0 taken 1641 times.
✓ Branch 1 taken 1802354 times.
✓ Branch 2 taken 1641 times.
✗ Branch 3 not taken.
1803995 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2320 }
2321 1804288 }
2322 1817285 c = MAPCOMBO(x,y);
2323
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1817285 times.
1817285 if(check_icy(combobuf[c], type)) return c;
2324 1817285 return 0;
2325 1821974 }
2326
2327 13049792 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2328 {
2329
8/8
✓ Branch 0 taken 13042994 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13034128 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13022496 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 428468 times.
✓ Branch 7 taken 12594028 times.
13049792 if(x<0 || x>=world_w || y<0 || y>=world_h)
2330 455764 return false;
2331
2332 12594028 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2333
2/4
✓ Branch 0 taken 12594028 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12594028 times.
12594028 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2334 return true;
2335
2336 12594028 change_rpos_handle_layer(rpos_handle, 1);
2337
2/2
✓ Branch 0 taken 7561110 times.
✓ Branch 1 taken 5032918 times.
12594028 if (rpos_handle.scr->is_valid())
2338
3/4
✓ Branch 0 taken 5032918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3279 times.
✓ Branch 3 taken 5029639 times.
5032918 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2339 3279 return true;
2340
2341 12590749 change_rpos_handle_layer(rpos_handle, 2);
2342
2/2
✓ Branch 0 taken 10831908 times.
✓ Branch 1 taken 1758841 times.
12590749 if (rpos_handle.scr->is_valid())
2343
2/4
✓ Branch 0 taken 1758841 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1758841 times.
1758841 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2344 return true;
2345
2346 12590749 return false;
2347 13049792 }
2348
2349 6589058 bool isSVLadder(int32_t x, int32_t y)
2350 {
2351 6589058 return checkSV(x, y, mfSIDEVIEWLADDER);
2352 }
2353
2354 6460734 bool isSVPlatform(int32_t x, int32_t y)
2355 {
2356 6460734 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2357 }
2358
2359 6460734 bool checkSVLadderPlatform(int32_t x, int32_t y)
2360 {
2361
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6460734 times.
✓ Branch 2 taken 6458937 times.
✓ Branch 3 taken 1797 times.
6460734 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2362 }
2363
2364 1637 bool isstepable(int32_t combo) //can use ladder on it
2365 {
2366
2/2
✓ Branch 0 taken 1631 times.
✓ Branch 1 taken 6 times.
1637 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2367
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2368 {
2369 if(combobuf[combo].usrflags&cflag4)
2370 {
2371 int32_t ldrid = current_item_id(itype_ladder);
2372 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2373 }
2374 }
2375 6 return false;
2376 1637 }
2377
2378 32780 bool isHSGrabbable(newcombo const& cmb)
2379 {
2380
2/2
✓ Branch 0 taken 373 times.
✓ Branch 1 taken 32407 times.
32780 if(cmb.type == cHSGRAB) return true;
2381 32407 return cmb.genflags & cflag1;
2382 32780 }
2383
2384 954 bool isSwitchHookable(newcombo const& cmb)
2385 {
2386
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2387 822 return cmb.genflags & cflag2;
2388 954 }
2389
2390 61401 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2391 {
2392 61401 rpos_t cpos = rpos_t::None;
2393
2/2
✓ Branch 0 taken 64592 times.
✓ Branch 1 taken 125993 times.
61401 if(out_rpos)
2394 {
2395 125993 int32_t id = MAPCOMBO2(layer-1,x,y);
2396
2/2
✓ Branch 0 taken 28634 times.
✓ Branch 1 taken 97359 times.
125993 if(id > 0)
2397 {
2398 97359 newcombo const& cmb = combobuf[id];
2399
4/4
✓ Branch 0 taken 32738 times.
✓ Branch 1 taken 64621 times.
✓ Branch 2 taken 32296 times.
✓ Branch 3 taken 32325 times.
97359 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2400 32767 }
2401 61401 }
2402
2403 125993 ffcdata* ffc = nullptr;
2404
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3393 times.
125993 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2405 {
2406 10359 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2407
2/2
✓ Branch 0 taken 6853 times.
✓ Branch 1 taken 113 times.
6966 if (ffcIsAt(ffc_handle, x, y))
2408 {
2409 113 auto& cmb = ffc_handle.combo();
2410
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 36 times.
113 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2411 {
2412 77 ffc = ffc_handle.ffc;
2413 77 return false;
2414 }
2415 36 }
2416 6889 return true;
2417 6896 });
2418 3393 }
2419
2420
4/4
✓ Branch 0 taken 61401 times.
✓ Branch 1 taken 64592 times.
✓ Branch 2 taken 442 times.
✓ Branch 3 taken 60959 times.
125993 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2421
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28382 times.
125993 if (out_ffc && ffc) *out_ffc = ffc;
2422
2/2
✓ Branch 0 taken 65034 times.
✓ Branch 1 taken 60959 times.
125993 return (cpos != rpos_t::None || ffc);
2423 }
2424
2425 5195 bool ishookshottable(int32_t bx, int32_t by)
2426 {
2427
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5195 times.
5195 if(!_walkflag(bx,by,1))
2428 return true;
2429
2430
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5187 times.
5195 if (collide_object(bx, by, 1, 1))
2431 8 return false;
2432
2433 5187 bool ret = true;
2434
2/2
✓ Branch 0 taken 15561 times.
✓ Branch 1 taken 1900 times.
17461 for(int32_t i=2; i>=0; i--)
2435 {
2436 15561 int32_t c = MAPCOMBO2(i-1,bx,by);
2437 15561 int32_t t = combobuf[c].type;
2438
2439
6/6
✓ Branch 0 taken 5187 times.
✓ Branch 1 taken 10374 times.
✓ Branch 2 taken 3853 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1900 times.
✓ Branch 5 taken 1953 times.
15561 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2440
2441
3/4
✓ Branch 0 taken 11321 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13227 bool dried = (iswater_type(t) && DRIEDLAKE);
2442
2443 12274 int32_t b=1;
2444
2445
2/2
✓ Branch 0 taken 6109 times.
✓ Branch 1 taken 6165 times.
12274 if(bx&8) b<<=2;
2446
2447
2/2
✓ Branch 0 taken 3841 times.
✓ Branch 1 taken 8433 times.
12274 if(by&8) b<<=1;
2448
2449
7/8
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 10180 times.
✓ Branch 2 taken 2094 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 979 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 904 times.
12274 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2450 904 ret = false;
2451 12274 }
2452
2453 1900 return ret;
2454 5195 }
2455
2456 10110 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2457 {
2458
4/4
✓ Branch 0 taken 9531 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 9531 times.
✓ Branch 3 taken 579 times.
10110 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2459 {
2460 579 int pos = COMBOPOS(s->stairx,s->stairy);
2461 579 s->data[pos] = s->secretcombo[sSTAIRS];
2462 579 s->cset[pos] = s->secretcset[sSTAIRS];
2463 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2464
2465
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2466 {
2467 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2468 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2469 256 }
2470
2471 579 return true;
2472 }
2473
2474 9531 return false;
2475 10110 }
2476
2477 51231 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2478 {
2479 DCHECK(base_scr->is_valid());
2480
2481 51231 screen_handles_t screen_handles{};
2482 51231 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2483 51231 return screen_handles;
2484 }
2485
2486 56545734 screen_handles_t create_screen_handles(mapscr* base_scr)
2487 {
2488 DCHECK(get_scr(base_scr->screen) == base_scr);
2489 DCHECK(base_scr->is_valid());
2490
2491 56545734 int screen = base_scr->screen;
2492 screen_handles_t screen_handles;
2493 56545734 screen_handles[0] = {base_scr, base_scr, screen, 0};
2494
2/2
✓ Branch 0 taken 339274404 times.
✓ Branch 1 taken 56545734 times.
395820138 for (int i = 1; i <= 6; i++)
2495 339274404 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2496 56545734 return screen_handles;
2497 }
2498
2499 106202 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2500 {
2501 106202 mapscr* scr = screen_handles[0].scr;
2502 106202 bool didit=false;
2503
2504
2/2
✓ Branch 0 taken 106202 times.
✓ Branch 1 taken 18691552 times.
18797754 for(int32_t i=0; i<176; i++)
2505 {
2506 18691552 newcombo const& cmb = combobuf[scr->data[i]];
2507
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 18691226 times.
18691552 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2508
4/4
✓ Branch 0 taken 18689693 times.
✓ Branch 1 taken 1533 times.
✓ Branch 2 taken 1102 times.
✓ Branch 3 taken 18688591 times.
18691226 if((cmb.type == what1) || (cmb.type== what2))
2509 {
2510 2635 scr->data[i]++;
2511 2635 didit=true;
2512 2635 }
2513 18691226 }
2514
2515
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 106110 times.
106202 if (do_layers)
2516 {
2517
2/2
✓ Branch 0 taken 636660 times.
✓ Branch 1 taken 106110 times.
742770 for(int32_t j=1; j<=6; j++)
2518 {
2519 636660 mapscr* layer_scr = screen_handles[j].scr;
2520
2/2
✓ Branch 0 taken 173130 times.
✓ Branch 1 taken 463530 times.
636660 if (!layer_scr) continue;
2521
2522
2/2
✓ Branch 0 taken 30470880 times.
✓ Branch 1 taken 173130 times.
30644010 for(int32_t i=0; i<176; i++)
2523 {
2524 30470880 newcombo const& cmb = combobuf[layer_scr->data[i]];
2525
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30470880 times.
30470880 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2526
4/4
✓ Branch 0 taken 30470797 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 265 times.
✓ Branch 3 taken 30470532 times.
30470880 if((cmb.type== what1) || (cmb.type== what2))
2527 {
2528 348 layer_scr->data[i]++;
2529 348 didit=true;
2530 348 }
2531 30470880 }
2532 173130 }
2533 106110 }
2534
2535 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2536
3/4
✓ Branch 0 taken 20406 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20406 times.
106202 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2537 {
2538 20406 word c = scr->numFFC();
2539
2/2
✓ Branch 0 taken 73350 times.
✓ Branch 1 taken 20406 times.
93756 for(word i=0; i<c; i++)
2540 {
2541 73350 ffcdata* ffc = &scr->ffcs[i];
2542 73350 newcombo const& cmb = combobuf[ffc->data];
2543
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73350 times.
73350 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2544
2/4
✓ Branch 0 taken 73350 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 73350 times.
73350 if((cmb.type== what1) || (cmb.type== what2))
2545 {
2546 zc_ffc_modify(*ffc, 1);
2547 didit=true;
2548 }
2549 73350 }
2550 20406 }
2551
2552 106202 return didit;
2553 }
2554
2555 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2556 {
2557 14 int screen = screen_handles[0].scr->screen;
2558
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2559 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2560 }
2561 471570670 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2562 {
2563 471570670 bool didit=false;
2564
2/2
✓ Branch 0 taken 471540241 times.
✓ Branch 1 taken 30429 times.
471570670 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2565
2566 30429 mapscr* s = screen_handles[0].scr;
2567 30429 int screen = s->screen;
2568 30429 bool is_active_screen = is_in_current_region(s);
2569
2570 25977933 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2571
4/4
✓ Branch 0 taken 11264 times.
✓ Branch 1 taken 25936240 times.
✓ Branch 2 taken 1808 times.
✓ Branch 3 taken 25945696 times.
25947504 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2572 1808 didit = true;
2573
2/2
✓ Branch 0 taken 63627 times.
✓ Branch 1 taken 25882069 times.
25945696 else switch (rpos_handle.ctype())
2574 {
2575 case cLOCKBLOCK: case cLOCKBLOCK2:
2576 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2577 case cCHEST: case cCHEST2:
2578 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2579 case cBOSSCHEST: case cBOSSCHEST2:
2580 {
2581 63627 auto& cmb = rpos_handle.combo();
2582
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 1568 times.
63627 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2583
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2584 {
2585 29 rpos_handle.increment_data();
2586 29 didit=true;
2587 29 }
2588 62059 break;
2589 }
2590 }
2591 25947504 });
2592
2593
4/4
✓ Branch 0 taken 30388 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 20768 times.
✓ Branch 3 taken 9620 times.
30429 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2594 {
2595 20768 word c = s->numFFC();
2596 20768 int screen_index_offset = get_region_screen_offset(screen);
2597
2/2
✓ Branch 0 taken 36840 times.
✓ Branch 1 taken 20768 times.
57608 for (uint8_t i = 0; i < c; i++)
2598 {
2599 36840 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2600 36840 auto& cmb = ffc_handle.combo();
2601
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 36840 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 36824 times.
36840 if(triggers && force_ex_trigger_any(ffc_handle, xflag))
2602 16 didit = true;
2603
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36824 times.
36824 else switch(cmb.type)
2604 {
2605 case cLOCKBLOCK: case cLOCKBLOCK2:
2606 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2607 case cCHEST: case cCHEST2:
2608 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2609 case cBOSSCHEST: case cBOSSCHEST2:
2610 {
2611 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2612 if(cmb.attribytes[5] == xflag)
2613 {
2614 zc_ffc_modify(*ffc_handle.ffc, 1);
2615 didit=true;
2616 }
2617 break;
2618 }
2619 }
2620 36840 }
2621 20768 }
2622
2623 30429 return didit;
2624 471570670 }
2625
2626 14685129 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2627 {
2628 14685129 int screen = screen_handles[0].screen;
2629
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14297296 times.
14685129 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2630 14685129 clear_xstatecombos_mi(screen_handles, mi, triggers);
2631 14685129 }
2632
2633 14736583 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2634 {
2635
2/2
✓ Branch 0 taken 471570656 times.
✓ Branch 1 taken 14736583 times.
486307239 for (int q = 0; q < 32; ++q)
2636 {
2637 471570656 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2638 471570656 }
2639 14736583 }
2640
2641 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2642 {
2643 int screen = screen_handles[0].screen;
2644 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2645 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2646 }
2647 471570656 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2648 {
2649 471570656 bool didit=false;
2650
2/2
✓ Branch 0 taken 471569343 times.
✓ Branch 1 taken 1313 times.
471570656 if (!getxdoor_mi(mi, dir, ind)) return false;
2651
2652 1313 mapscr* scr = screen_handles[0].scr;
2653 1313 int screen = scr->screen;
2654 1313 bool is_active_screen = is_in_current_region(scr);
2655
2656 925665 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2657
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 924352 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 924341 times.
924352 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2658 11 didit = true;
2659 else; //future door combo types?
2660 924352 });
2661
2662
2/4
✓ Branch 0 taken 1313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1313 times.
✗ Branch 3 not taken.
1313 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2663 {
2664 1313 word c = scr->numFFC();
2665 1313 int screen_index_offset = get_region_screen_offset(screen);
2666
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1313 times.
1313 for (uint8_t i = 0; i < c; i++)
2667 {
2668 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2669 if (triggers && force_ex_door_trigger_any(ffc_handle, dir, ind))
2670 didit = true;
2671 else; //future door combo types?
2672 }
2673 1313 }
2674
2675 1313 return didit;
2676 471570656 }
2677
2678 14685129 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2679 {
2680 14685129 int screen = screen_handles[0].screen;
2681
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14297296 times.
14685129 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2682 14685129 return clear_xdoors_mi(screen_handles, mi, triggers);
2683 }
2684
2685 14736583 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2686 {
2687
2/2
✓ Branch 0 taken 58946332 times.
✓ Branch 1 taken 14736583 times.
73682915 for (int dir = 0; dir < 4; ++dir)
2688
2/2
✓ Branch 0 taken 471570656 times.
✓ Branch 1 taken 58946332 times.
530516988 for (int q = 0; q < 8; ++q)
2689 530516988 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2690 14736583 }
2691
2692 763 bool remove_lockblocks(const screen_handles_t& screen_handles)
2693 {
2694 763 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2695 }
2696
2697 98 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2698 {
2699 98 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2700 }
2701
2702 76553 bool remove_chests(const screen_handles_t& screen_handles)
2703 {
2704 76553 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2705 }
2706
2707 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2708 {
2709 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2710 }
2711
2712 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2713 {
2714 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2715 }
2716
2717 1384361 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2718 {
2719 1384361 int32_t ct=rpos_handle.ctype();
2720
2721
6/6
✓ Branch 0 taken 1383741 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1383489 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1383381 times.
✓ Branch 5 taken 108 times.
1384361 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2722 1383381 return;
2723
2724 2465 auto [cx, cy] = rpos_handle.xy();
2725
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2726 {
2727 case cL_STATUE:
2728 620 cx += 4;
2729 620 cy += 7;
2730 620 break;
2731
2732 case cR_STATUE:
2733 252 cx -= 8;
2734 252 cy -= 1;
2735 252 break;
2736
2737 case cC_STATUE:
2738 108 break;
2739 }
2740
2741
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2742 {
2743 // Finds the smallest enemy ID
2744
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2745 {
2746 346 guys.del(j);
2747 346 }
2748 1485 }
2749 1384361 }
2750
2751 15 static int32_t findtrigger(int32_t screen)
2752 {
2753 15 int32_t checkflag=0;
2754 15 int32_t ret = 0;
2755
2756 mapscr* screens[7];
2757
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 15 times.
120 for (int32_t j = 0; j <= 6; j++)
2758 {
2759 105 screens[j] = get_scr_layer_valid(screen, j);
2760 105 }
2761
2762 15 bool sflag = false;
2763
2/2
✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 15 times.
2655 for(word j=0; j<176; j++)
2764 {
2765
2/2
✓ Branch 0 taken 26752 times.
✓ Branch 1 taken 2640 times.
29392 for(int32_t layer = -1; layer < 6; ++layer)
2766 {
2767 26752 mapscr* scr = screens[layer+1];
2768
2/2
✓ Branch 0 taken 16544 times.
✓ Branch 1 taken 10208 times.
26752 if (!scr) continue;
2769
2770
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if(sflag)
2771 8272 checkflag = scr->sflag[j];
2772 else
2773 8272 checkflag = combobuf[scr->data[j]].flag;
2774 16544 sflag = !sflag;
2775
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if (sflag) --layer;
2776
2777
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 16534 times.
16544 switch(checkflag)
2778 {
2779 case mfANYFIRE:
2780 case mfSTRONGFIRE:
2781 case mfMAGICFIRE:
2782 case mfDIVINEFIRE:
2783 case mfARROW:
2784 case mfSARROW:
2785 case mfGARROW:
2786 case mfSBOMB:
2787 case mfBOMB:
2788 case mfBRANG:
2789 case mfMBRANG:
2790 case mfFBRANG:
2791 case mfWANDMAGIC:
2792 case mfREFMAGIC:
2793 case mfREFFIREBALL:
2794 case mfSWORD:
2795 case mfWSWORD:
2796 case mfMSWORD:
2797 case mfXSWORD:
2798 case mfSWORDBEAM:
2799 case mfWSWORDBEAM:
2800 case mfMSWORDBEAM:
2801 case mfXSWORDBEAM:
2802 case mfHOOKSHOT:
2803 case mfWAND:
2804 case mfHAMMER:
2805 case mfSTRIKE:
2806 10 ret += 1;
2807 10 break;
2808 }
2809 16544 }
2810 2640 }
2811
2812 15 return ret;
2813 }
2814
2815 11738 static void log_trigger_secret_reason(TriggerSource source)
2816 {
2817
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11299 times.
11738 if (source == TriggerSource::Singular)
2818 {
2819 439 Z_eventlog("Restricted Screen Secrets triggered\n");
2820 439 }
2821 else
2822 {
2823 11299 const char* source_str = "";
2824
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7178 times.
✓ Branch 3 taken 856 times.
✓ Branch 4 taken 2733 times.
✓ Branch 5 taken 475 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 52 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11299 switch (source)
2825 {
2826 case TriggerSource::Singular: break;
2827 7178 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2828 856 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2829 2733 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2830 475 case TriggerSource::Script: source_str = "a script"; break;
2831 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2832 52 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2833 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2834 case TriggerSource::SCC: source_str = "SCC"; break;
2835 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2836 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2837 }
2838 11299 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2839 }
2840 11738 }
2841
2842 // single:
2843 // >-1 : the singular triggering combo
2844 // -1: triggered by some other cause
2845 11530 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2846 {
2847 11530 log_trigger_secret_reason(source);
2848
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11091 times.
11530 if (single < 0)
2849 11091 get_screen_state(scr->screen).triggered_secrets = true;
2850
2851 11530 bool do_replay_comment = true;
2852 11530 bool from_active_screen = true;
2853 11530 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2854
2855 // Respect secret state carryovers for active screens.
2856
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11091 times.
11530 if (single >= 0) return;
2857
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 11068 times.
11091 if(scr->nocarry&mSECRET) return;
2858 11068 int cmap = scr->map;
2859 11068 int cscr = scr->screen;
2860 11068 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2861 11068 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2862
2863 11068 std::vector<int32_t> done;
2864
2/2
✓ Branch 0 taken 10896 times.
✓ Branch 1 taken 172 times.
11068 bool looped = (nmap==cmap+1 && nscr==cscr);
2865
2866
6/6
✓ Branch 0 taken 484 times.
✓ Branch 1 taken 11001 times.
✓ Branch 2 taken 67 times.
✓ Branch 3 taken 417 times.
✓ Branch 4 taken 417 times.
✓ Branch 5 taken 11068 times.
11485 while((nmap!=0) && !looped && !(nscr>=128))
2867 {
2868
7/8
✓ Branch 0 taken 317 times.
✓ Branch 1 taken 100 times.
✓ Branch 2 taken 74 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 74 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 70 times.
417 if (nmap - 1 == cur_map && is_in_current_region(nscr) && !get_screen_state(nscr).triggered_secrets)
2869 {
2870
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2871
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2872
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2873 4 }
2874
2875 417 cmap=nmap;
2876 417 cscr=nscr;
2877 417 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2878 417 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2879
2880
2/2
✓ Branch 0 taken 386 times.
✓ Branch 1 taken 417 times.
803 for(auto it = done.begin(); it != done.end(); it++)
2881 {
2882
2/2
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 67 times.
386 if(*it == ((nmap-1)<<7)+nscr)
2883 67 looped = true;
2884 386 }
2885
2886
1/2
✓ Branch 0 taken 417 times.
✗ Branch 1 not taken.
417 done.push_back(((nmap-1)<<7)+nscr);
2887 }
2888 11530 }
2889
2890 2437 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2891 {
2892 2437 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2893 2437 }
2894
2895 18007 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2896 {
2897 18007 mapscr* scr = screen_handles[0].scr;
2898 18007 int screen = scr->screen;
2899
2900 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2901 // slopes in sideview mode (which required loading nearby screens in loadscr).
2902 // TODO(replays): This should just use `screen`.
2903
3/4
✓ Branch 0 taken 18007 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 17468 times.
18007 if (replay_is_active() && do_replay_comment)
2904
4/6
✓ Branch 0 taken 11534 times.
✓ Branch 1 taken 5934 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11534 times.
✓ Branch 4 taken 17468 times.
✗ Branch 5 not taken.
17468 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2905
2906
2/2
✓ Branch 0 taken 6473 times.
✓ Branch 1 taken 11534 times.
18007 if (from_active_screen)
2907 {
2908 5529590 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2909
2/4
✓ Branch 0 taken 5516368 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1688 times.
✗ Branch 3 not taken.
5834885 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
2910 316829 return trig.trigger_flags.get(TRIGFLAG_SECRETSTR);
2911 }, ctrigSECRETS);
2912 5518056 });
2913 11534 }
2914
2915 18007 int32_t ft=0; //Flag trigger?
2916 18007 int32_t msflag=0; // Misc. secret flag
2917
2918
2/2
✓ Branch 0 taken 3169232 times.
✓ Branch 1 taken 18007 times.
3187239 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2919 {
2920
4/4
✓ Branch 0 taken 77264 times.
✓ Branch 1 taken 3091968 times.
✓ Branch 2 taken 439 times.
✓ Branch 3 taken 76825 times.
3169232 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2921
2922 // Remember the misc. secret flag; if triggered, use this instead
2923
4/4
✓ Branch 0 taken 114511 times.
✓ Branch 1 taken 2977896 times.
✓ Branch 2 taken 49462 times.
✓ Branch 3 taken 65049 times.
3092407 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2924 65049 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2925
4/4
✓ Branch 0 taken 47230 times.
✓ Branch 1 taken 2980128 times.
✓ Branch 2 taken 46999 times.
✓ Branch 3 taken 231 times.
3027358 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2926 231 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2927 else
2928 3027127 msflag=0;
2929
2930
4/4
✓ Branch 0 taken 921256 times.
✓ Branch 1 taken 2171151 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 921184 times.
3092407 if(!high16only || single>=0)
2931 {
2932 2171223 int32_t newflag = -1;
2933
2934
2/2
✓ Branch 0 taken 4342446 times.
✓ Branch 1 taken 2171223 times.
6513669 for(int32_t iter=0; iter<2; ++iter)
2935 {
2936 4342446 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2937
2938
2/2
✓ Branch 0 taken 2171223 times.
✓ Branch 1 taken 2171223 times.
4342446 if(iter==1) checkflag=scr->sflag[i]; //Placed
2939
2940 4342446 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2941
2/2
✓ Branch 0 taken 4330212 times.
✓ Branch 1 taken 12234 times.
4342446 if (ft != -1) //Change the combos for the secret
2942 {
2943 // Use misc. secret flag instead if one is present
2944
2/2
✓ Branch 0 taken 12202 times.
✓ Branch 1 taken 32 times.
12234 if(msflag!=0)
2945 32 ft=msflag;
2946
2947 12234 rpos_handle_t rpos_handle;
2948
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2949 {
2950 5867 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2951 5867 screen_combo_modify_preroutine(rpos_handle);
2952 5867 }
2953
2954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12234 times.
12234 if(ft==sSECNEXT)
2955 {
2956 scr->data[i]++;
2957 }
2958 else
2959 {
2960 12234 scr->data[i] = scr->secretcombo[ft];
2961 12234 scr->cset[i] = scr->secretcset[ft];
2962 }
2963 12234 newflag = scr->secretflag[ft];
2964
2965
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2966 5867 screen_combo_modify_postroutine(rpos_handle);
2967 12234 }
2968 4342446 }
2969
2970
2/2
✓ Branch 0 taken 2158995 times.
✓ Branch 1 taken 12228 times.
2171223 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2971
2972
2/2
✓ Branch 0 taken 13027338 times.
✓ Branch 1 taken 2171223 times.
15198561 for(int32_t j=1; j<=6; j++) //Layers
2973 {
2974 13027338 mapscr* layer_scr = screen_handles[j].scr;
2975
2/2
✓ Branch 0 taken 3213077 times.
✓ Branch 1 taken 9814261 times.
13027338 if (!layer_scr) continue;
2976
2977
3/4
✓ Branch 0 taken 725 times.
✓ Branch 1 taken 3212352 times.
✓ Branch 2 taken 725 times.
✗ Branch 3 not taken.
3213077 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2978
2979 3213077 int32_t newflag2 = -1;
2980
2981 // Remember the misc. secret flag; if triggered, use this instead
2982
4/4
✓ Branch 0 taken 14182 times.
✓ Branch 1 taken 3198895 times.
✓ Branch 2 taken 4773 times.
✓ Branch 3 taken 9409 times.
3213077 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2983 9409 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2984
4/4
✓ Branch 0 taken 126931 times.
✓ Branch 1 taken 3076737 times.
✓ Branch 2 taken 126560 times.
✓ Branch 3 taken 371 times.
3203668 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2985 371 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2986 else
2987 3203297 msflag=0;
2988
2989
2/2
✓ Branch 0 taken 6426154 times.
✓ Branch 1 taken 3213077 times.
9639231 for(int32_t iter=0; iter<2; ++iter)
2990 {
2991 6426154 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2992
2/2
✓ Branch 0 taken 3213077 times.
✓ Branch 1 taken 3213077 times.
6426154 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2993
2994 6426154 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2995
2/2
✓ Branch 0 taken 6425676 times.
✓ Branch 1 taken 478 times.
6426154 if (ft != -1) //Change the combos for the secret
2996 {
2997 // Use misc. secret flag instead if one is present
2998
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 2 times.
478 if(msflag!=0)
2999 2 ft=msflag;
3000
3001
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 478 times.
478 if(ft==sSECNEXT)
3002 {
3003 layer_scr->data[i]++;
3004 }
3005 else
3006 {
3007 478 layer_scr->data[i] = layer_scr->secretcombo[ft];
3008 478 layer_scr->cset[i] = layer_scr->secretcset[ft];
3009 }
3010 478 newflag2 = layer_scr->secretflag[ft];
3011 478 int32_t c=layer_scr->data[i];
3012 478 int32_t cs=layer_scr->cset[i];
3013
3014
3/4
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 406 times.
✗ Branch 3 not taken.
478 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
3015 {
3016 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
3017 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
3018 }
3019 478 }
3020 6426154 }
3021
3022
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 3212599 times.
3213077 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
3023 3213077 }
3024 2171223 }
3025 3092407 }
3026
3027 18007 word c = scr->numFFC();
3028
2/2
✓ Branch 0 taken 506903 times.
✓ Branch 1 taken 18007 times.
524910 for(word i=0; i<c; i++) //FFC 'trigger flags'
3029 {
3030
3/4
✓ Branch 0 taken 492983 times.
✓ Branch 1 taken 13920 times.
✓ Branch 2 taken 13920 times.
✗ Branch 3 not taken.
506903 if(single>=0) if(i+176!=single) continue;
3031
3032
3/4
✓ Branch 0 taken 166605 times.
✓ Branch 1 taken 326378 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166605 times.
492983 if((!high16only)||(single>=0))
3033 {
3034 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
3035 {
3036 326378 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3037 //No placed flags yet
3038
3039 326378 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
3040
2/2
✓ Branch 0 taken 326347 times.
✓ Branch 1 taken 31 times.
326378 if (ft != -1) //Change the ffc's combo
3041 {
3042
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
3043 {
3044 zc_ffc_modify(scr->ffcs[i], 1);
3045 }
3046 else
3047 {
3048 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
3049 31 scr->ffcs[i].cset = scr->secretcset[ft];
3050 }
3051 31 }
3052 }
3053 326378 }
3054 492983 }
3055
3056
2/2
✓ Branch 0 taken 15610 times.
✓ Branch 1 taken 2397 times.
18007 if(checktrigger) //Hit all triggers->16-31
3057 {
3058 2397 checktrigger=false;
3059
3060
2/2
✓ Branch 0 taken 2388 times.
✓ Branch 1 taken 9 times.
2397 if(scr->flags6&fTRIGGERF1631)
3061 {
3062 9 int32_t tr = findtrigger(screen); //Normal flags
3063
3064
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if(tr)
3065 {
3066 5 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
3067 5 goto endhe;
3068 }
3069 4 }
3070 2392 }
3071
3072
2/2
✓ Branch 0 taken 3168352 times.
✓ Branch 1 taken 18002 times.
3186354 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
3073 {
3074 //If it's an enemies->secret screen, only do the high 16 if told to
3075 //That way you can have secret and burn/bomb entrance separately
3076 3168352 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
3077
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 387728 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3083168 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3168352 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
3078 {
3079 3102704 int32_t newflag = -1;
3080
3081
2/2
✓ Branch 0 taken 6205408 times.
✓ Branch 1 taken 3102704 times.
9308112 for(int32_t iter=0; iter<2; ++iter)
3082 {
3083 6205408 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
3084
3085
2/2
✓ Branch 0 taken 3102704 times.
✓ Branch 1 taken 3102704 times.
6205408 if(iter==1) checkflag=scr->sflag[i]; //Placed
3086
3087
4/4
✓ Branch 0 taken 161185 times.
✓ Branch 1 taken 6044223 times.
✓ Branch 2 taken 94853 times.
✓ Branch 3 taken 66332 times.
6205408 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3088 {
3089 66332 rpos_handle_t rpos_handle;
3090
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 56380 times.
66332 if (from_active_screen)
3091 {
3092 56380 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3093 56380 screen_combo_modify_preroutine(rpos_handle);
3094 56380 }
3095
3096 66332 scr->data[i] = scr->secretcombo[checkflag-16+4];
3097 66332 scr->cset[i] = scr->secretcset[checkflag-16+4];
3098 66332 newflag = scr->secretflag[checkflag-16+4];
3099
3100
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 56380 times.
66332 if (from_active_screen)
3101 56380 screen_combo_modify_postroutine(rpos_handle);
3102 66332 }
3103 6205408 }
3104
3105
2/2
✓ Branch 0 taken 3036396 times.
✓ Branch 1 taken 66308 times.
3102704 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3106
3107
2/2
✓ Branch 0 taken 18616224 times.
✓ Branch 1 taken 3102704 times.
21718928 for(int32_t j=1; j<=6; j++) //Layers
3108 {
3109 18616224 mapscr* layer_scr = screen_handles[j].scr;
3110
2/2
✓ Branch 0 taken 4895440 times.
✓ Branch 1 taken 13720784 times.
18616224 if (!layer_scr) continue;
3111
3112 4895440 int32_t newflag2 = -1;
3113
3114
2/2
✓ Branch 0 taken 9790880 times.
✓ Branch 1 taken 4895440 times.
14686320 for(int32_t iter=0; iter<2; ++iter)
3115 {
3116 9790880 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3117
3118
2/2
✓ Branch 0 taken 4895440 times.
✓ Branch 1 taken 4895440 times.
9790880 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3119
3120
4/4
✓ Branch 0 taken 151246 times.
✓ Branch 1 taken 9639634 times.
✓ Branch 2 taken 131622 times.
✓ Branch 3 taken 19624 times.
9790880 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3121 {
3122 19624 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3123 19624 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3124 19624 newflag2 = layer_scr->secretflag[checkflag-16+4];
3125 19624 }
3126 9790880 }
3127
3128
2/2
✓ Branch 0 taken 4875816 times.
✓ Branch 1 taken 19624 times.
4895440 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3129 4895440 }
3130 3102704 }
3131 3168352 }
3132
3133
2/2
✓ Branch 0 taken 506743 times.
✓ Branch 1 taken 18002 times.
524745 for(word i=0; i<c; i++) // FFCs
3134 {
3135
6/6
✓ Branch 0 taken 466852 times.
✓ Branch 1 taken 39891 times.
✓ Branch 2 taken 15367 times.
✓ Branch 3 taken 491376 times.
✓ Branch 4 taken 3530 times.
✓ Branch 5 taken 11837 times.
506743 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3136 {
3137 494906 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3138
3139 //No placed flags yet
3140
4/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 494838 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 12 times.
494906 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3141 {
3142
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3143 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3144 else
3145 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3146 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3147 12 }
3148 494906 }
3149 524745 }
3150
3151 endhe:
3152
3153
1/2
✓ Branch 0 taken 18007 times.
✗ Branch 1 not taken.
18007 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3154 {
3155 if (from_active_screen)
3156 activated_timed_warp = true;
3157 scr->timedwarptics = 0;
3158 }
3159 18007 }
3160
3161 // x,y are world coordinates.
3162 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3163 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3164 13546841 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3165 {
3166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13546841 times.
13546841 if (!is_in_world_bounds(x, y)) return false;
3167
3168 13546841 bool found_cflag = false;
3169 13546841 bool found_nflag = false;
3170 13546841 bool single16 = false;
3171 13546841 rpos_t rpos = rpos_t::None;
3172
3173
2/2
✓ Branch 0 taken 13544757 times.
✓ Branch 1 taken 94815695 times.
108360452 for (int32_t layer = -1; layer < 6; layer++)
3174 {
3175
2/2
✓ Branch 0 taken 94813611 times.
✓ Branch 1 taken 2084 times.
94815695 if (MAPFLAG2(layer, x, y) == flag)
3176 {
3177 2084 found_nflag = true;
3178 2084 break;
3179 }
3180 94813611 }
3181
3182
2/2
✓ Branch 0 taken 13546537 times.
✓ Branch 1 taken 94826611 times.
108373148 for (int32_t layer = -1; layer < 6; layer++)
3183 {
3184
2/2
✓ Branch 0 taken 94826307 times.
✓ Branch 1 taken 304 times.
94826611 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3185 {
3186 304 found_cflag = true;
3187 304 break;
3188 }
3189 94826307 }
3190
3191
2/2
✓ Branch 0 taken 94827887 times.
✓ Branch 1 taken 13546841 times.
108374728 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3192 {
3193
2/2
✓ Branch 0 taken 94813299 times.
✓ Branch 1 taken 14588 times.
94827887 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3194 {
3195
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14476 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14588 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3196 {
3197 112 rpos = COMBOPOS_REGION(x, y);
3198 112 }
3199
3/4
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 14424 times.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
14476 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3200 {
3201 52 rpos = COMBOPOS_REGION(x, y);
3202 52 single16 = true;
3203 52 }
3204 14588 }
3205
3206
2/2
✓ Branch 0 taken 94825759 times.
✓ Branch 1 taken 2128 times.
94827887 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3207 {
3208
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 1873 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2128 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3209 {
3210 255 rpos = COMBOPOS_REGION(x, y);
3211 255 }
3212
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1853 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
1873 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3213 {
3214 20 rpos = COMBOPOS_REGION(x, y);
3215 20 single16 = true;
3216 20 }
3217 2128 }
3218 94827887 }
3219
3220 13546841 out_rpos = rpos;
3221 13546841 out_single16 = single16;
3222
4/4
✓ Branch 0 taken 13544757 times.
✓ Branch 1 taken 2084 times.
✓ Branch 2 taken 13544455 times.
✓ Branch 3 taken 302 times.
13546841 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3223 13546841 }
3224
3225 4477821 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3226 {
3227
8/8
✓ Branch 0 taken 4477581 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4475684 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4475164 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4474212 times.
4477821 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3228
3229 4474212 mapscr* scr = NULL;
3230 4474212 int32_t screen = -1;
3231 4474212 rpos_t trigger_rpos = rpos_t::None;
3232 4474212 bool single16 = false;
3233
3234 4474212 std::vector<std::pair<int, int>> coords;
3235
1/2
✓ Branch 0 taken 4474212 times.
✗ Branch 1 not taken.
4474212 coords.push_back({x, y});
3236
1/2
✓ Branch 0 taken 4474212 times.
✗ Branch 1 not taken.
4474212 coords.push_back({x + 15, y});
3237
1/2
✓ Branch 0 taken 4474212 times.
✗ Branch 1 not taken.
4474212 coords.push_back({x, y + 15});
3238
1/2
✓ Branch 0 taken 4474212 times.
✗ Branch 1 not taken.
4474212 coords.push_back({x + 15, y + 15});
3239 4474212 std::vector<rpos_t> rposes_seen;
3240
2/2
✓ Branch 0 taken 4471815 times.
✓ Branch 1 taken 17891566 times.
84820223 for (auto [x, y] : coords)
3241 {
3242
2/4
✓ Branch 0 taken 17891566 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17891566 times.
✗ Branch 3 not taken.
35783132 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3243
2/2
✓ Branch 0 taken 17679183 times.
✓ Branch 1 taken 212383 times.
17891566 if (rpos == rpos_t::None)
3244 212383 continue;
3245
3246
4/6
✓ Branch 0 taken 17679183 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17679183 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 17679172 times.
35358366 if (MAPFFCOMBOFLAG(x, y) == flag)
3247 {
3248
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3249 11 break;
3250 }
3251
3252 17679172 bool seen = false;
3253
2/2
✓ Branch 0 taken 13546841 times.
✓ Branch 1 taken 22206797 times.
35753638 for (rpos_t r : rposes_seen)
3254 {
3255
2/2
✓ Branch 0 taken 18074466 times.
✓ Branch 1 taken 4132331 times.
22206797 if (r == rpos)
3256 {
3257 4132331 seen = true;
3258 4132331 break;
3259 }
3260 }
3261
2/2
✓ Branch 0 taken 13546841 times.
✓ Branch 1 taken 4132331 times.
17679172 if (seen)
3262 4132331 continue;
3263
3264
1/2
✓ Branch 0 taken 13546841 times.
✗ Branch 1 not taken.
13546841 rposes_seen.push_back(rpos);
3265
4/6
✓ Branch 0 taken 13546841 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13546841 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2386 times.
✓ Branch 5 taken 13544455 times.
27093682 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3266 {
3267
2/4
✓ Branch 0 taken 2386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2386 times.
✗ Branch 3 not taken.
4772 screen = get_screen_for_world_xy(x, y);
3268 2386 break;
3269 }
3270 }
3271
3272
3/4
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4471815 times.
✓ Branch 2 taken 2397 times.
✗ Branch 3 not taken.
4474212 if (screen != -1) scr = get_scr(screen);
3273
2/2
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4471815 times.
4474212 if (!scr) return false;
3274
3275
2/2
✓ Branch 0 taken 1958 times.
✓ Branch 1 taken 439 times.
2397 if (trigger_rpos == rpos_t::None)
3276 {
3277 1958 checktrigger = true;
3278
1/2
✓ Branch 0 taken 1958 times.
✗ Branch 1 not taken.
1958 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3279 1958 }
3280 else
3281 {
3282 439 checktrigger = true;
3283
2/4
✓ Branch 0 taken 439 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 439 times.
✗ Branch 3 not taken.
439 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3284 }
3285
3286
1/2
✓ Branch 0 taken 2397 times.
✗ Branch 1 not taken.
2397 sfx(scr->secretsfx);
3287
3288
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2391 times.
2397 if(scr->flags6&fTRIGGERFPERM)
3289 {
3290
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int32_t flags_remaining = findtrigger(screen); //Normal flags
3291
3292
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (flags_remaining)
3293 {
3294
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3295 3 setflag=false;
3296 3 }
3297
3298 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3299 // which case only the screen state for mSECRET may be set below.
3300
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3301 {
3302 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3303 }
3304 6 }
3305
3306
5/6
✓ Branch 0 taken 2292 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 2292 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1184 times.
2397 if (setflag && canPermSecret(cur_dmap, screen))
3307
2/2
✓ Branch 0 taken 721 times.
✓ Branch 1 taken 463 times.
1905 if(!(scr->flags5&fTEMPSECRETS))
3308
1/2
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
721 setmapflag(scr, mSECRET);
3309
3310 2397 return true;
3311 4477821 }
3312
3313 14811877 void update_slopes()
3314 {
3315
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 14811877 times.
14954233 for (auto& p : slopes)
3316 {
3317 142356 slope_object& s = p.second;
3318 142356 s.updateslope(); //sets old x/y poses
3319 }
3320 14811877 }
3321
3322 14405233 void update_freeform_combos()
3323 {
3324 14405233 ffscript_engine(false);
3325
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14381061 times.
14405233 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3326 {
3327 14381061 int wrap_right = world_w + 32;
3328 14381061 int wrap_bottom = world_h + 32;
3329
3330 485523595 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3331 471142534 mapscr* scr = ffc_handle.scr;
3332 471142534 ffcdata& thisffc = *ffc_handle.ffc;
3333
3334 // Combo 0?
3335
2/2
✓ Branch 0 taken 44992239 times.
✓ Branch 1 taken 426150295 times.
471142534 if(thisffc.data==0)
3336 426150295 return;
3337
3338 // Changer?
3339
2/2
✓ Branch 0 taken 543029 times.
✓ Branch 1 taken 44449210 times.
44992239 if(thisffc.flags&ffc_changer)
3340 543029 return;
3341
3342 // Stationary?
3343
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 44439366 times.
44449210 if(thisffc.flags&ffc_stationary)
3344 9844 return;
3345
3346 // Frozen because Hero's holding up an item?
3347
3/4
✓ Branch 0 taken 138282 times.
✓ Branch 1 taken 44301084 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 138282 times.
44439366 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3348 138282 return;
3349
3350 // Check for changers
3351
2/2
✓ Branch 0 taken 29543786 times.
✓ Branch 1 taken 14757298 times.
44301084 if (thisffc.link==0)
3352 {
3353 442453159 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3354
2/2
✓ Branch 0 taken 14755762 times.
✓ Branch 1 taken 412940099 times.
427695861 if (ffc_handle.id == other_ffc_handle.id)
3355 14755762 return true;
3356
3357 412940099 ffcdata& otherffc = *other_ffc_handle.ffc;
3358 // Combo 0?
3359
2/2
✓ Branch 0 taken 144689583 times.
✓ Branch 1 taken 268250516 times.
412940099 if(otherffc.data==0)
3360 268250516 return true;
3361
3362 // Not a changer?
3363
2/2
✓ Branch 0 taken 140701406 times.
✓ Branch 1 taken 3988177 times.
144689583 if(!(otherffc.flags&ffc_changer))
3364 140701406 return true;
3365
3366 // Ignore this changer?
3367
4/4
✓ Branch 0 taken 546579 times.
✓ Branch 1 taken 3441598 times.
✓ Branch 2 taken 299257 times.
✓ Branch 3 taken 3142341 times.
3988177 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3368 845836 return true;
3369
3370
3/4
✓ Branch 0 taken 2721043 times.
✓ Branch 1 taken 421298 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3562 times.
3145903 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3371 ( // At exactly the same position,
3372
2/2
✓ Branch 0 taken 208792 times.
✓ Branch 1 taken 2512251 times.
2721043 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3373
2/2
✓ Branch 0 taken 2303459 times.
✓ Branch 1 taken 2512251 times.
208792 ||
3374 //or imprecision and close enough
3375
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5024502 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3376 )
3377 && //and...
3378
2/2
✓ Branch 0 taken 3562 times.
✓ Branch 1 taken 2721195 times.
2724757 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3379 {
3380 3562 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3381 3562 return false;
3382 }
3383
3384 2721195 return true;
3385 426679763 });
3386 14757298 }
3387
3388
2/2
✓ Branch 0 taken 29543786 times.
✓ Branch 1 taken 14757298 times.
44301084 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3389
4/4
✓ Branch 0 taken 14757298 times.
✓ Branch 1 taken 29543786 times.
✓ Branch 2 taken 14680008 times.
✓ Branch 3 taken 14863778 times.
44301084 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3390 {
3391
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 14681169 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
14863778 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3392 {
3393 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3394 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3395 97278 thisffc.x += linked_ffc->vx;
3396 97278 thisffc.y += linked_ffc->vy;
3397 97278 }
3398 else
3399 {
3400 14766500 thisffc.prev_changer_x = thisffc.x.getZLong();
3401 14766500 thisffc.prev_changer_y = thisffc.y.getZLong();
3402 14766500 thisffc.x += thisffc.vx;
3403 14766500 thisffc.y += thisffc.vy;
3404 14766500 thisffc.vx += thisffc.ax;
3405 14766500 thisffc.vy += thisffc.ay;
3406
3407
3408
2/2
✓ Branch 0 taken 444046 times.
✓ Branch 1 taken 14322454 times.
14766500 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3409 {
3410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx>128) thisffc.vx=128;
3411
3412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx<-128) thisffc.vx=-128;
3413
3414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy>128) thisffc.vy=128;
3415
3416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy<-128) thisffc.vy=-128;
3417 14322454 }
3418 }
3419 14863778 }
3420 else
3421 {
3422
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76129 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
29437306 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3423 76129 thisffc.delay--;
3424 }
3425
3426 // Check if the FFC's off the side of the screen
3427
3428 // Left
3429
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 14930619 times.
14941068 if(thisffc.x<-32)
3430 {
3431
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3432 {
3433 253 thisffc.x = wrap_right+(thisffc.x+32);
3434 253 thisffc.solid_update(false);
3435 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3436 // Re-enable previous changer
3437 253 thisffc.changer_x = -1000;
3438 253 thisffc.changer_y = -1000;
3439 253 }
3440
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3441 {
3442 69 zc_ffc_set(thisffc, 0);
3443 69 thisffc.flags&=~ffc_carryover;
3444 69 }
3445 10449 }
3446 // Right
3447
2/2
✓ Branch 0 taken 14930438 times.
✓ Branch 1 taken 181 times.
14930619 else if(thisffc.x>=wrap_right)
3448 {
3449
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3450 {
3451 128 thisffc.x = thisffc.x-wrap_right-32;
3452 128 thisffc.solid_update(false);
3453 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3454 128 thisffc.changer_x = -1000;
3455 128 thisffc.changer_y = -1000;
3456 128 }
3457 else
3458 {
3459 53 zc_ffc_set(thisffc, 0);
3460 53 thisffc.flags&=~ffc_carryover;
3461 }
3462 181 }
3463
3464 // Top
3465
2/2
✓ Branch 0 taken 25480 times.
✓ Branch 1 taken 14915588 times.
14941068 if(thisffc.y<-32)
3466 {
3467
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25472 times.
25480 if(scr->flags6&fWRAPAROUNDFF)
3468 {
3469 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3470 8 thisffc.solid_update(false);
3471 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3472 8 thisffc.changer_x = -1000;
3473 8 thisffc.changer_y = -1000;
3474 8 }
3475
2/2
✓ Branch 0 taken 25155 times.
✓ Branch 1 taken 317 times.
25472 else if(thisffc.y<-64)
3476 {
3477 317 zc_ffc_set(thisffc, 0);
3478 317 thisffc.flags&=~ffc_carryover;
3479 317 }
3480 25480 }
3481 // Bottom
3482
2/2
✓ Branch 0 taken 14914744 times.
✓ Branch 1 taken 844 times.
14915588 else if(thisffc.y>=wrap_bottom)
3483 {
3484
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 91 times.
844 if(scr->flags6&fWRAPAROUNDFF)
3485 {
3486 753 thisffc.y = thisffc.y-wrap_bottom-32;
3487 753 thisffc.solid_update(false);
3488 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3489 753 thisffc.changer_x = -1000;
3490 753 thisffc.changer_y = -1000;
3491 753 }
3492 else
3493 {
3494 91 zc_ffc_set(thisffc, 0);
3495 91 thisffc.flags&=~ffc_carryover;
3496 }
3497 844 }
3498 14941068 thisffc.solid_update();
3499 441782518 });
3500 14381061 }
3501 14405233 }
3502
3503 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3504 {
3505 for(int q = 0; q < 7; ++q)
3506 {
3507 if(layers&(1<<q)) //if layer is to be checked
3508 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3509 return true;
3510 }
3511 return false;
3512 }
3513
3514 231 optional<int> nextscr(int screen, int dir)
3515 {
3516 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3517
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3518 462 return (m<<7) + s;
3519 231 }
3520
3521 1058 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3522 {
3523 1058 int32_t map = cur_map;
3524
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1058 times.
1058 int32_t screen = screenscrolling ? scrolling_hero_screen : Hero.current_screen;
3525 1058 return nextscr2(map, screen, dir);
3526 }
3527
3528 5576 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3529 {
3530 5576 screen = screen_index_direction(screen, (direction)dir);
3531
3532 // need to check for screens on other maps, 's' not valid, etc.
3533 5576 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3534
3535 // Fun fact: when a scrolling warp is triggered, this function
3536 // is never even called! - Saf
3537
2/2
✓ Branch 0 taken 3326 times.
✓ Branch 1 taken 2250 times.
6120 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3538 {
3539
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 525 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 697 times.
2250 switch(dir)
3540 {
3541 case up:
3542
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3543
3544 83 break;
3545
3546 case down:
3547
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 446 times.
525 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3548
3549 79 break;
3550
3551 case left:
3552
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 337 times.
546 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3553
3554 209 break;
3555
3556 case right:
3557
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 524 times.
697 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3558
3559 173 break;
3560 }
3561
3562 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3563 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3564 544 }
3565
3566 nowarp:
3567
4/4
✓ Branch 0 taken 5512 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5400 times.
5576 if(screen<0||screen>=128)
3568 176 return {-1, -1};
3569
3570 5400 return {map, screen};
3571 5576 }
3572
3573 403 optional<int> nextscr_mi(int mi, int dir)
3574 {
3575 403 int map = mi/MAPSCRSNORMAL;
3576 403 int screen = mi%MAPSCRSNORMAL;
3577 403 auto [m, s] = nextscr2(map, screen, dir);
3578
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3579 804 return (m<<7) + s;
3580 403 }
3581
3582 2114 void bombdoor(int32_t x,int32_t y)
3583 {
3584
2/2
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 20 times.
2114 if (!is_in_world_bounds(x, y))
3585 20 return;
3586
3587 2094 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3588 2094 mapscr* scr = rpos_handle.scr;
3589 2094 int screen = scr->screen;
3590 2902 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3591 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3592
3593
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2015 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2094 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3594 {
3595 69 scr->door[0]=dBOMBED;
3596 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3597 69 setmapflag(scr, mDOOR_UP);
3598 69 markBmap(-1, screen);
3599
3600
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3601 {
3602 69 setmapflag_mi(*v, mDOOR_DOWN);
3603 69 markBmap(-1,*v-(get_currdmap()<<7));
3604 69 }
3605 69 }
3606
3607
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2045 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2094 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3608 {
3609 39 scr->door[1]=dBOMBED;
3610 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3611 39 setmapflag(scr, mDOOR_DOWN);
3612 39 markBmap(-1, rpos_handle.screen);
3613
3614
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3615 {
3616 39 setmapflag_mi(*v, mDOOR_UP);
3617 39 markBmap(-1,*v-(get_currdmap()<<7));
3618 39 }
3619 39 }
3620
3621
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2027 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2094 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3622 {
3623 51 scr->door[2]=dBOMBED;
3624 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3625 51 setmapflag(scr, mDOOR_LEFT);
3626 51 markBmap(-1, rpos_handle.screen);
3627
3628
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3629 {
3630 51 setmapflag_mi(*v, mDOOR_RIGHT);
3631 51 markBmap(-1,*v-(get_currdmap()<<7));
3632 51 }
3633 51 }
3634
3635
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2008 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2094 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3636 {
3637 72 scr->door[3]=dBOMBED;
3638 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3639 72 setmapflag(scr, mDOOR_RIGHT);
3640 72 markBmap(-1, rpos_handle.screen);
3641
3642
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3643 {
3644 72 setmapflag_mi(*v, mDOOR_LEFT);
3645 72 markBmap(-1,*v-(get_currdmap()<<7));
3646 72 }
3647 72 }
3648 2114 }
3649
3650 6518321194 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3651 bool over, bool transp)
3652 {
3653 6518321194 auto& cmb = combobuf[cid];
3654
2/2
✓ Branch 0 taken 93673 times.
✓ Branch 1 taken 6518227521 times.
6518321194 if(cmb.animflags & AF_EDITOR_ONLY)
3655 93673 return;
3656
2/2
✓ Branch 0 taken 3443366591 times.
✓ Branch 1 taken 3074860930 times.
6518227521 if(over)
3657 {
3658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3443366591 times.
3443366591 if(cmb.animflags & AF_TRANSPARENT)
3659 transp = !transp;
3660
2/2
✓ Branch 0 taken 319148412 times.
✓ Branch 1 taken 3124218179 times.
3443366591 if(transp)
3661 319148412 overcombotranslucent(dest, x, y, cid, cset, 128);
3662 3124218179 else overcombo(dest, x, y, cid, cset);
3663 3443366591 }
3664 3074860930 else putcombo(dest, x, y, cid, cset);
3665 6518321194 }
3666 6518329642 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3667 int32_t cset, byte layer, bool over, bool transp)
3668 {
3669
2/2
✓ Branch 0 taken 755578275 times.
✓ Branch 1 taken 5762751367 times.
6518329642 if (rpos != rpos_t::None)
3670 {
3671 5762751367 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3672
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 5762001843 times.
5762751367 if (plrpos != rpos_t::None)
3673 {
3674 5762001843 bool dosw = false;
3675
4/4
✓ Branch 0 taken 67632 times.
✓ Branch 1 taken 5761934211 times.
✓ Branch 2 taken 59184 times.
✓ Branch 3 taken 8448 times.
5762001843 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3676 {
3677
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3678 {
3679 draw_cmb(dest, x, y,
3680 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3681 }
3682 8448 dosw = true;
3683 8448 }
3684
4/4
✓ Branch 0 taken 32707713 times.
✓ Branch 1 taken 5729285682 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 32699265 times.
5761993395 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3685 {
3686 8448 dosw = true;
3687 8448 }
3688
2/2
✓ Branch 0 taken 5761984947 times.
✓ Branch 1 taken 16896 times.
5762001843 if (dosw)
3689 {
3690
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3691 {
3692 default: case swPOOF:
3693 break; //Nothing special here
3694 case swFLICKER:
3695 {
3696
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3697 8448 break; //Drawn this frame
3698 8448 return; //Not drawn this frame
3699 }
3700 case swRISE:
3701 {
3702 //Draw rising up
3703 y -= 8-(abs(Hero.switchhookclk-32)/4);
3704 break;
3705 }
3706 }
3707 8448 }
3708 5761993395 }
3709 5762742919 }
3710
3711 6518321194 draw_cmb(dest, x, y, cid, cset, over, transp);
3712 6518329642 }
3713
3714 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3715 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3716 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3717 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3718 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3719 //
3720 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3721 //
3722 // -16 < comboPositionX*16 + x < bitmapWidth
3723 // -16 < comboPositionY*16 + y < bitmapHeight
3724 //
3725 // The following start/end values are derived directly from the above.
3726 //
3727 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3728 40264391 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3729 {
3730 // if (bmp->clip)
3731 // {
3732 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3733 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3734 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3735 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3736 // return;
3737 // }
3738
3739
2/2
✓ Branch 0 taken 2181084 times.
✓ Branch 1 taken 38083307 times.
40264391 start_x = MAX(0, ceil((-15 - x) / 16.0));
3740
2/2
✓ Branch 0 taken 2189800 times.
✓ Branch 1 taken 38074591 times.
40264391 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3741
2/2
✓ Branch 0 taken 38869048 times.
✓ Branch 1 taken 1395343 times.
40264391 start_y = MAX(0, ceil((-15 - y) / 16.0));
3742
2/2
✓ Branch 0 taken 1687374 times.
✓ Branch 1 taken 38577017 times.
40264391 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3743 40264391 }
3744
3745 187098564 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3746 {
3747
1/2
✓ Branch 0 taken 187098564 times.
✗ Branch 1 not taken.
187098564 if(!show_ffcs) return;
3748 187098564 mapscr* scr = screen_handle.scr;
3749 187098564 mapscr* base_scr = screen_handle.base_scr;
3750
3751 187098564 y += playing_field_offset;
3752
3753 187098564 bool is_overhead = layer == -1000;
3754
2/2
✓ Branch 0 taken 51004367 times.
✓ Branch 1 taken 136094197 times.
187098564 bool is_bg_layer = layer < 0 && !is_overhead;
3755
2/2
✓ Branch 0 taken 34038248 times.
✓ Branch 1 taken 153060316 times.
187098564 int real_layer = is_bg_layer ? abs(layer) : layer;
3756
2/2
✓ Branch 0 taken 187098564 times.
✓ Branch 1 taken 5583749632 times.
5770848196 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3757 {
3758
2/2
✓ Branch 0 taken 205507335 times.
✓ Branch 1 taken 5378242297 times.
5583749632 if (base_scr->ffcs[i].data == 0)
3759 5378242297 continue;
3760
3/4
✓ Branch 0 taken 37365904 times.
✓ Branch 1 taken 168141431 times.
✓ Branch 2 taken 37365904 times.
✗ Branch 3 not taken.
205507335 if (is_bg_layer && base_scr->ffcs[i].layer == layer)
3761 ; // ffc is set negative, skip bg layer flag checks
3762 else
3763 {
3764
4/4
✓ Branch 0 taken 37365904 times.
✓ Branch 1 taken 168141431 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 18682952 times.
205507335 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3765 18682952 continue;
3766
4/4
✓ Branch 0 taken 37365729 times.
✓ Branch 1 taken 149458654 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 18682777 times.
186824383 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3767 18682777 continue;
3768
4/4
✓ Branch 0 taken 149463616 times.
✓ Branch 1 taken 18677990 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 130780664 times.
168141606 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3769 130780664 continue;
3770 }
3771
3772
6/6
✓ Branch 0 taken 3008970 times.
✓ Branch 1 taken 34351972 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3003860 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
37360942 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3773 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3774
3775 37358458 base_scr->ffcs[i].draw_ffc(bmp, x, y, is_overhead);
3776 37358458 }
3777 187098564 }
3778 170984295 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3779 {
3780
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 170984295 times.
170984295 if(!show_ffcs) return;
3781 346546812 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3782 175562517 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3783 175562517 do_ffc_layer(bmp, layer, handle, 0, 0);
3784 175562517 });
3785 170984295 }
3786 76514215 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3787 {
3788 76514215 mapscr* scr = screen_handle.scr;
3789 76514215 mapscr* base_scr = screen_handle.base_scr;
3790
3791
4/4
✓ Branch 0 taken 61873867 times.
✓ Branch 1 taken 14640348 times.
✓ Branch 2 taken 14640348 times.
✓ Branch 3 taken 76514215 times.
76514215 if (type == -3 || type == -4)
3792 {
3793 29280696 y += playing_field_offset;
3794
3795
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
29280696 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3796 {
3797 if (base_scr->ffcs[i].data == 0)
3798 continue;
3799
3800 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3801 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3802
3803 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3804 }
3805 return;
3806 }
3807
3808 76514215 x -= viewport.x;
3809 76514215 y -= viewport.y - playing_field_offset;
3810
3811 76514215 bool over = true, transp = false;
3812 76514215 int layer = screen_handle.layer;
3813
3814
7/8
✓ Branch 0 taken 55268805 times.
✓ Branch 1 taken 21245410 times.
✓ Branch 2 taken 13425432 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 34166331 times.
✓ Branch 5 taken 21102474 times.
✓ Branch 6 taken 3177949 times.
✓ Branch 7 taken 4642029 times.
76514215 switch(type ? type : layer)
3815 {
3816 case -2: //push blocks
3817
2/2
✓ Branch 0 taken 19525983 times.
✓ Branch 1 taken 14640348 times.
34166331 if (scr)
3818 {
3819
2/2
✓ Branch 0 taken 3436573008 times.
✓ Branch 1 taken 23800175 times.
3436235675 for(int32_t i=0; i<176; i++)
3820 {
3821 3436573008 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3822
3823
10/10
✓ Branch 0 taken 3436402664 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3434930692 times.
✓ Branch 3 taken 1471972 times.
✓ Branch 4 taken 3434301709 times.
✓ Branch 5 taken 628983 times.
✓ Branch 6 taken 24420859 times.
✓ Branch 7 taken 3409880850 times.
✓ Branch 8 taken 42762999 times.
✓ Branch 9 taken 16868491 times.
3473620476 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3824
6/8
✓ Branch 0 taken 3431420180 times.
✓ Branch 1 taken 21539330 times.
✓ Branch 2 taken 3431420180 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3431420180 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37047468 times.
✓ Branch 7 taken 3394372712 times.
3434301709 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3825 {
3826
4/4
✓ Branch 0 taken 4772507 times.
✓ Branch 1 taken 695982 times.
✓ Branch 2 taken 3657 times.
✓ Branch 3 taken 4768850 times.
90994487 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3827 5468489 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3828 5468489 }
3829 3416709692 }
3830 23800175 }
3831 38440523 return;
3832
3833 case -1: //over combo
3834
1/2
✓ Branch 0 taken 21102474 times.
✗ Branch 1 not taken.
21102474 if (scr)
3835 {
3836
2/2
✓ Branch 0 taken 3714035424 times.
✓ Branch 1 taken 21102474 times.
3735137898 for(int32_t i=0; i<176; i++)
3837 {
3838
2/2
✓ Branch 0 taken 3694759368 times.
✓ Branch 1 taken 19276056 times.
3714035424 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3839 {
3840
4/4
✓ Branch 0 taken 15523213 times.
✓ Branch 1 taken 3752843 times.
✓ Branch 2 taken 22320 times.
✓ Branch 3 taken 15500893 times.
19276056 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3841 19276056 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3842 19276056 }
3843 3714035424 }
3844 21102474 }
3845 21102474 return;
3846
3847 case 1:
3848 case 4:
3849 case 5:
3850 case 6:
3851
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13425432 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
13425432 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3852 {
3853
1/2
✓ Branch 0 taken 13425432 times.
✗ Branch 1 not taken.
13425432 if (scr)
3854 {
3855
2/2
✓ Branch 0 taken 11766221 times.
✓ Branch 1 taken 1659211 times.
13425432 if(base_scr->layeropacity[layer-1]!=255)
3856 1659211 transp = true;
3857 13425432 break;
3858 }
3859 }
3860 return;
3861
3862 case 2:
3863
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3177949 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3177949 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3864 {
3865
1/2
✓ Branch 0 taken 3177949 times.
✗ Branch 1 not taken.
3177949 if (scr)
3866 {
3867
2/2
✓ Branch 0 taken 2958352 times.
✓ Branch 1 taken 219597 times.
3177949 if(base_scr->layeropacity[layer-1]!=255)
3868 219597 transp = true;
3869
3870
2/2
✓ Branch 0 taken 3049040 times.
✓ Branch 1 taken 128909 times.
3177949 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3871 128909 over = false;
3872
3873 3177949 break;
3874 }
3875 }
3876 return;
3877
3878 case 3:
3879
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4642029 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4642029 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3880 {
3881
1/2
✓ Branch 0 taken 4642029 times.
✗ Branch 1 not taken.
4642029 if (scr)
3882 {
3883
2/2
✓ Branch 0 taken 4568316 times.
✓ Branch 1 taken 73713 times.
4642029 if(base_scr->layeropacity[layer-1]!=255)
3884 73713 transp = true;
3885
3886
2/2
✓ Branch 0 taken 36654 times.
✓ Branch 1 taken 60483 times.
4642029 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3887
2/2
✓ Branch 0 taken 97137 times.
✓ Branch 1 taken 4544892 times.
4642029 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3888 60483 over = false;
3889
3890 4642029 break;
3891 }
3892 }
3893 return;
3894 }
3895
3896 int start_x, end_x, start_y, end_y;
3897 21245410 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3898
2/2
✓ Branch 0 taken 21245410 times.
✓ Branch 1 taken 225471985 times.
246717395 for (int cy = start_y; cy < end_y; cy++)
3899 {
3900
2/2
✓ Branch 0 taken 3417234455 times.
✓ Branch 1 taken 225471985 times.
3642706440 for (int cx = start_x; cx < end_x; cx++)
3901 {
3902 3417234455 int i = cx + cy*16;
3903
4/4
✓ Branch 0 taken 3034081004 times.
✓ Branch 1 taken 383153451 times.
✓ Branch 2 taken 10099056 times.
✓ Branch 3 taken 3023981948 times.
3417234455 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3904 3417234455 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3905 3417234455 }
3906 225471985 }
3907 61873867 }
3908
3909 269046153 bool lenscheck(mapscr* scr, int layer)
3910 {
3911
4/4
✓ Branch 0 taken 268867205 times.
✓ Branch 1 taken 178948 times.
✓ Branch 2 taken 178948 times.
✓ Branch 3 taken 269046153 times.
269046153 if(layer < 0 || layer > 6) return true;
3912
2/2
✓ Branch 0 taken 259588626 times.
✓ Branch 1 taken 9457527 times.
269046153 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3913 {
3914
2/2
✓ Branch 0 taken 209710465 times.
✓ Branch 1 taken 49878161 times.
259588626 if(!layer) return true;
3915
8/8
✓ Branch 0 taken 34922371 times.
✓ Branch 1 taken 174788094 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34663401 times.
✓ Branch 4 taken 143758 times.
✓ Branch 5 taken 163336 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34480623 times.
209710465 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3916 489872 return false;
3917 209268717 }
3918 else
3919 {
3920
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9457527 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9457527 times.
9457527 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3921 return false;
3922 }
3923 218726244 return true;
3924 268867205 }
3925
3926 156193367 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3927 {
3928 156193367 bool showlayer = true;
3929 156193367 mapscr* base_scr = screen_handle.base_scr;
3930 156193367 int layer = screen_handle.layer;
3931
2/2
✓ Branch 0 taken 42102029 times.
✓ Branch 1 taken 114091338 times.
156193367 int target = type ? type : layer;
3932
3/4
✓ Branch 0 taken 114091338 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20239778 times.
✓ Branch 3 taken 21862251 times.
156193367 switch(target)
3933 {
3934 case -2:
3935
1/2
✓ Branch 0 taken 20239778 times.
✗ Branch 1 not taken.
20239778 if(!show_layer_push)
3936 showlayer = false;
3937 20239778 break;
3938
3939 case -1:
3940
1/2
✓ Branch 0 taken 21862251 times.
✗ Branch 1 not taken.
21862251 if(!show_layer_over)
3941 showlayer = false;
3942 21862251 break;
3943
3944 case 1: case 2: case 3:
3945 case 4: case 5: case 6:
3946 114091338 showlayer = show_layers[target];
3947 114091338 break;
3948 }
3949
3950
2/2
✓ Branch 0 taken 42102029 times.
✓ Branch 1 taken 114091338 times.
156193367 if(!type)
3951 {
3952
2/2
✓ Branch 0 taken 113955140 times.
✓ Branch 1 taken 136198 times.
114091338 if(!lenscheck(base_scr,layer))
3953 136198 showlayer = false;
3954 114091338 }
3955
3956
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 156057169 times.
156193367 if(showlayer)
3957 {
3958
6/6
✓ Branch 0 taken 61929990 times.
✓ Branch 1 taken 94127179 times.
✓ Branch 2 taken 21301533 times.
✓ Branch 3 taken 40628457 times.
✓ Branch 4 taken 56123 times.
✓ Branch 5 taken 21245410 times.
156057169 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3959 {
3960 61873867 do_scrolling_layer(bmp, type, screen_handle, x, y);
3961
4/4
✓ Branch 0 taken 21245410 times.
✓ Branch 1 taken 40628457 times.
✓ Branch 2 taken 19248580 times.
✓ Branch 3 taken 1996830 times.
61873867 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3962
2/2
✓ Branch 0 taken 1996254 times.
✓ Branch 1 taken 576 times.
1997406 if(mblock2.draw(bmp,layer))
3963 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3964 61873867 }
3965 156057169 }
3966 156193367 }
3967
3968 103043001 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3969 {
3970 103043001 bool showlayer = true;
3971
3972
2/4
✓ Branch 0 taken 103043001 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 103043001 times.
103043001 if(layer >= 0 && layer <= 6)
3973 {
3974 103043001 showlayer = show_layers[layer];
3975
3976
2/2
✓ Branch 0 taken 102916399 times.
✓ Branch 1 taken 126602 times.
103043001 if(!lenscheck(origin_scr,layer))
3977 126602 showlayer = false;
3978 103043001 }
3979
3980
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 102916399 times.
103043001 if (showlayer)
3981 102916399 do_primitives(bmp, layer);
3982 103043001 }
3983
3984 // Called by do_walkflags
3985 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3986 {
3987 newcombo const &c = combobuf[cmbdat];
3988
3989 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3990
3991 int32_t xx = x-xofs;
3992 int32_t yy = y+playing_field_offset-yofs;
3993
3994 int32_t bridgedetected = 0;
3995
3996 for(int32_t i=0; i<4; i++)
3997 {
3998 int32_t tx=((i&2)<<2)+xx - viewport.x;
3999 int32_t ty=((i&1)<<3)+yy - viewport.y;
4000 int32_t tx2=((i&2)<<2)+x - viewport.x;
4001 int32_t ty2=((i&1)<<3)+y - viewport.y;
4002 for (int32_t j = lyr-1; j <= 1; j++)
4003 {
4004 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4005 {
4006 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
4007 {
4008 bridgedetected |= (1<<i);
4009 }
4010 }
4011 else
4012 {
4013 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
4014 {
4015 bridgedetected |= (1<<i);
4016 }
4017 }
4018 }
4019 if ((bridgedetected & (1<<i)))
4020 {
4021 if (i >= 3) break;
4022 else continue;
4023 }
4024 bool doladdercheck = true;
4025
4026 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4027 {
4028 for(int32_t k=0; k<8; k+=2)
4029 for(int32_t j=0; j<8; j+=2)
4030 if(((k+j)/2)%2)
4031 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
4032 }
4033 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4034 {
4035 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4036 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4037 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
4038 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
4039 }
4040
4041 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4042 {
4043 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4044 {
4045 for(int32_t k=0; k<8; k+=2)
4046 for(int32_t j=0; j<8; j+=2)
4047 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
4048 }
4049 else
4050 {
4051 int32_t color = makecol(178,36,36);
4052
4053 if(isstepable(cmbdat)&& (!doladdercheck))
4054 color=makecol(165,105,8);
4055 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4056 color=makecol(170,170,170);
4057
4058 rectfill(dest,tx,ty,tx+7,ty+7,color);
4059 }
4060 }
4061 }
4062
4063 // Draw damage combos
4064 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
4065 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
4066 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
4067
4068 if(dmg)
4069 {
4070 int32_t color = makecol(255,255,0);
4071 if (bridgedetected <= 0)
4072 {
4073 for(int32_t k=0; k<16; k+=2)
4074 for(int32_t j=0; j<16; j+=2)
4075 if(((k+j)/2)%2)
4076 {
4077 int32_t x0 = x - viewport.x;
4078 int32_t y0 = y - viewport.y;
4079 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4080 }
4081 }
4082 else
4083 {
4084 for(int32_t i=0; i<4; i++)
4085 {
4086 if (!(bridgedetected & (1<<i)))
4087 {
4088 int32_t tx=((i&2)<<2)+x - viewport.x;
4089 int32_t ty=((i&1)<<3)+y - viewport.y;
4090 for(int32_t k=0; k<8; k+=2)
4091 for(int32_t j=0; j<8; j+=2)
4092 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4093 }
4094 }
4095 }
4096 }
4097 }
4098 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4099 {
4100 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4101 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4102 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4103 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4104 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4105 newcombo const &c = combobuf[cmbdat];
4106
4107 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4108
4109 int32_t xx = x-viewport.x;
4110 int32_t yy = y+playing_field_offset-viewport.y;
4111
4112 int32_t bridgedetected = 0;
4113
4114 // Draw damage combos
4115 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4116
4117 for(int32_t i=0; i<4; i++)
4118 {
4119 int32_t tx=((i&2)<<2)+xx;
4120 int32_t ty=((i&1)<<3)+yy;
4121 int32_t tx2=((i&2)<<2)+x;
4122 int32_t ty2=((i&1)<<3)+y;
4123 for (int32_t m = lyr-1; m <= 1; m++)
4124 {
4125 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4126 {
4127 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4128 {
4129 bridgedetected |= (1<<i);
4130 }
4131 }
4132 else
4133 {
4134 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4135 {
4136 bridgedetected |= (1<<i);
4137 }
4138 }
4139 }
4140 if ((bridgedetected & (1<<i)))
4141 continue;
4142 bool doladdercheck = true;
4143
4144 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4145 {
4146 for(int32_t k=0; k<8; k+=2)
4147 for(int32_t j=0; j<8; j+=2)
4148 if(((k+j)/2)%2)
4149 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4150 }
4151 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4152 {
4153 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4154 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4155 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4156 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4157 }
4158
4159 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4160 {
4161 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4162 {
4163 for(int32_t k=0; k<8; k+=2)
4164 for(int32_t j=0; j<8; j+=2)
4165 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4166 }
4167 else
4168 {
4169 ALLEGRO_COLOR* color = &col_solid;
4170
4171 if(isstepable(cmbdat)&& (!doladdercheck))
4172 color=&col_stepable;
4173 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4174 color=&col_lhook;
4175
4176 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4177 }
4178 }
4179
4180 if(dmg)
4181 {
4182 for(int32_t k=0; k<8; k+=2)
4183 for(int32_t j=0; j<8; j+=2)
4184 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4185 }
4186 }
4187 }
4188
4189 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4190 {
4191 newcombo const &c = combobuf[cmbdat];
4192
4193 int32_t xx = x-xofs-viewport.x;
4194 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4195
4196 for(int32_t i=0; i<4; i++)
4197 {
4198 int32_t tx=((i&2)<<2)+xx;
4199 int32_t ty=((i&1)<<3)+yy;
4200
4201 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4202 {
4203 int32_t color = vc(10);
4204
4205 rectfill(dest,tx,ty,tx+7,ty+7,color);
4206 }
4207 }
4208 }
4209 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4210 {
4211 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4212 newcombo const &c = combobuf[cmbdat];
4213
4214 int32_t xx = x-viewport.x;
4215 int32_t yy = y+playing_field_offset-viewport.y;
4216
4217 for(int32_t i=0; i<4; i++)
4218 {
4219 int32_t tx=((i&2)<<2)+xx;
4220 int32_t ty=((i&1)<<3)+yy;
4221
4222 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4223 {
4224 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4225 }
4226 }
4227 }
4228
4229 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4230 {
4231 for(auto cx = 0; cx < 256; cx += 16)
4232 {
4233 for(auto cy = 0; cy < 176; cy += 16)
4234 {
4235 if(isSVLadder(cx,cy))
4236 {
4237 auto nx = cx+x, ny = cy+y;
4238 if(cy && !isSVLadder(cx,cy-16))
4239 line(dest,nx,ny,nx+15,ny,c);
4240 rectfill(dest,nx,ny,nx+3,ny+15,c);
4241 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4242 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4243 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4244 }
4245 else if(isSVPlatform(cx,cy))
4246 {
4247 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4248 }
4249 }
4250 }
4251 }
4252 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4253 {
4254 for(auto cx = 0; cx < 256; cx += 16)
4255 {
4256 for(auto cy = 0; cy < 176; cy += 16)
4257 {
4258 if(isSVLadder(cx,cy))
4259 {
4260 auto nx = cx+x, ny = cy+y;
4261 if(cy && !isSVLadder(cx,cy-16))
4262 al_draw_line(nx,ny,nx+15,ny,c,1);
4263 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4264 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4265 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4266 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4267 }
4268 else if(isSVPlatform(cx,cy))
4269 {
4270 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4271 }
4272 }
4273 }
4274 }
4275
4276 // Walkflags L4 cheat
4277 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4278 {
4279 if (!show_walkflags)
4280 return;
4281
4282 start_info_bmp();
4283
4284 mapscr* scr = screen_handles[0].scr;
4285 for(int32_t i=0; i<176; i++)
4286 {
4287 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4288 }
4289
4290 for(int32_t k=0; k<2; k++)
4291 {
4292 scr = screen_handles[k + 1].scr;
4293
4294 if (scr)
4295 {
4296 for(int32_t i=0; i<176; i++)
4297 {
4298 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4299 }
4300 }
4301 }
4302
4303 end_info_bmp();
4304 }
4305
4306 void do_walkflags(int32_t x, int32_t y)
4307 {
4308 if (!show_walkflags)
4309 return;
4310
4311 x += -viewport.x;
4312 y += playing_field_offset - viewport.y;
4313
4314 start_info_bmp();
4315
4316 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4317 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4318 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4319
4320 end_info_bmp();
4321 }
4322
4323 // Effectflags L4 cheat
4324 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4325 {
4326 if(show_effectflags)
4327 {
4328 start_info_bmp();
4329
4330 for(int32_t i=0; i<176; i++)
4331 {
4332 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4333 }
4334
4335 end_info_bmp();
4336 }
4337 }
4338
4339 272141 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4340 {
4341 272141 int map = scr->map;
4342 272141 int screen = scr->screen;
4343
4344
2/2
✓ Branch 0 taken 1904987 times.
✓ Branch 1 taken 272141 times.
2177128 for(int32_t lyr = 0; lyr < 7; ++lyr)
4345 {
4346 1904987 mapscr* scr = get_scr_layer(map, screen, lyr);
4347
2/2
✓ Branch 0 taken 1279588 times.
✓ Branch 1 taken 625399 times.
1904987 if (!scr->is_valid()) continue;
4348
4349
2/2
✓ Branch 0 taken 225207488 times.
✓ Branch 1 taken 1279588 times.
226487076 for(int32_t q = 0; q < 176; ++q)
4350 {
4351 225207488 newcombo const& cmb = combobuf[scr->data[q]];
4352
2/2
✓ Branch 0 taken 224602869 times.
✓ Branch 1 taken 604619 times.
225207488 if(cmb.type == cTORCH)
4353 {
4354 604619 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4355 604619 }
4356 225207488 }
4357 1279588 }
4358 272141 }
4359
4360 272141 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4361 {
4362 272141 word c = scr->numFFC();
4363
2/2
✓ Branch 0 taken 537406 times.
✓ Branch 1 taken 272141 times.
809547 for(int q = 0; q < c; ++q)
4364 {
4365 537406 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4366
2/2
✓ Branch 0 taken 522598 times.
✓ Branch 1 taken 14808 times.
537406 if(cmb.type == cTORCH)
4367 {
4368 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4369 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4370 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4371 14808 }
4372 537406 }
4373 272141 }
4374
4375 struct nearby_screen_t
4376 {
4377 int screen;
4378 int offx;
4379 int offy;
4380 screen_handles_t screen_handles;
4381 };
4382 typedef std::vector<nearby_screen_t> nearby_screens_t;
4383
4384 15490741 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4385 {
4386 15490741 nearby_screens_t nearby_screens;
4387
4388 15490741 mapscr* base_scr = origin_scr;
4389
1/2
✓ Branch 0 taken 15490741 times.
✗ Branch 1 not taken.
15490741 auto& nearby_screen = nearby_screens.emplace_back();
4390 15490741 nearby_screen.screen = cur_screen;
4391
1/2
✓ Branch 0 taken 15490741 times.
✗ Branch 1 not taken.
15490741 nearby_screen.screen_handles = create_screen_handles(base_scr);
4392
4393 15490741 return nearby_screens;
4394
1/2
✓ Branch 0 taken 15490741 times.
✗ Branch 1 not taken.
15490741 }
4395
4396 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4397 {
4398 48296 nearby_screens_t nearby_screens;
4399
4400
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4401
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4402
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4403
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4404
4405
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4406
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4407
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4408
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4409
4410
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4411 {
4412
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4413 {
4414 169672 int screen = cur_screen + x + y*16;
4415
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4416
4417
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4418
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4419
4420
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4421
4422
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4423 169672 nearby_screen.screen = screen;
4424 169672 nearby_screen.offx = offx;
4425 169672 nearby_screen.offy = offy;
4426
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4427 169672 }
4428 79928 }
4429
4430 48296 return nearby_screens;
4431
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4432
4433 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4434 {
4435 3658 nearby_screens_t nearby_screens;
4436
4437
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4438
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4439
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4440
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4441
4442
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4443
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4444
4445
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4446 {
4447
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4448 {
4449 18600 int screen = -1;
4450 mapscr* base_scr;
4451 int offx, offy;
4452
4453 18600 mapscr* maze_scr = maze_state.scr;
4454 18600 int maze_screen = maze_scr->screen;
4455
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4456
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4457 18600 int maze_screen_dx = x - maze_screen_x;
4458 18600 int maze_screen_dy = y - maze_screen_y;
4459 18600 int exitdir = maze_scr->exitdir;
4460
4461 bool should_draw_maze_screen;
4462
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4463 {
4464 9548 should_draw_maze_screen = true;
4465 9548 }
4466 else
4467 {
4468 9052 should_draw_maze_screen = true;
4469
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4470
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4471
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4472 }
4473
4474
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4475 {
4476 16048 screen = maze_state.scr->screen;
4477 16048 base_scr = maze_state.scr;
4478
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4479 16048 }
4480
4481
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4482 {
4483 2552 screen = cur_screen + x + y*16;
4484
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4485
4486
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4487
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4488
4489
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4490 2552 }
4491
4492
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4493 18600 nearby_screen.screen = screen;
4494 18600 nearby_screen.offx = offx;
4495 18600 nearby_screen.offy = offy;
4496
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4497 18600 }
4498 7308 }
4499
4500 3658 return nearby_screens;
4501
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4502
4503 15542695 static nearby_screens_t get_nearby_screens()
4504 {
4505
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 15533481 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
15542695 if (maze_state.active && maze_state.loopy)
4506 3658 return get_nearby_screens_smooth_maze();
4507
4508
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 15490741 times.
15539037 if (is_in_scrolling_region())
4509 48296 return get_nearby_screens_scrolling_region();
4510
4511 15490741 return get_nearby_screens_non_scrolling_region();
4512 15542695 }
4513
4514 202076528 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4515 {
4516
2/2
✓ Branch 0 taken 203861130 times.
✓ Branch 1 taken 202076528 times.
405937658 for (auto& nearby_screen : nearby_screens)
4517 203861130 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4518 202076528 }
4519
4520 124341560 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4521 {
4522
2/2
✓ Branch 0 taken 15542695 times.
✓ Branch 1 taken 108798865 times.
124341560 if(layer != msgstr_layer) return;
4523
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 if(!dest) dest = framebuf;
4524
4525
2/2
✓ Branch 0 taken 679438 times.
✓ Branch 1 taken 14863257 times.
15542695 if(!(msg_bg_display_buf->clip))
4526 {
4527 679438 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4528 679438 }
4529
4530
2/2
✓ Branch 0 taken 679438 times.
✓ Branch 1 taken 14863257 times.
15542695 if(!(msg_portrait_display_buf->clip))
4531 {
4532 679438 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4533 679438 }
4534
4535
2/2
✓ Branch 0 taken 692845 times.
✓ Branch 1 taken 14849850 times.
15542695 if(!(msg_txt_display_buf->clip))
4536 {
4537 692845 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4538 692845 }
4539 124341560 }
4540
4541 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4542
4543 62170780 static void set_draw_screen_clip(BITMAP* bmp)
4544 {
4545 62170780 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4546 62170780 }
4547
4548 17580 static void draw_sprites(BITMAP* dest, set<sprite*, SpriteSorter>& sprite_set, set<sprite*, SpriteSorter>::iterator& it, word upto_z)
4549 {
4550 17580 bool checkz = upto_z != word(-1); // max value represents "infinity" height
4551
6/6
✓ Branch 0 taken 11145 times.
✓ Branch 1 taken 6435 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 6275 times.
✓ Branch 4 taken 12905 times.
✓ Branch 5 taken 4675 times.
17580 if(it == sprite_set.end() || (checkz && (*it)->total_z() >= upto_z))
4552 12905 return; // no sprites to draw remaining
4553 // Just clips sprites if in a repeating, smooth maze.
4554
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 bool do_clip = maze_state.active && maze_state.loopy;
4555
4556
4557
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4558 {
4559 int maze_screen = maze_state.scr->screen;
4560 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4561 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4562 }
4563
6/6
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 32443 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 32283 times.
✓ Branch 4 taken 4675 times.
✓ Branch 5 taken 30698 times.
67816 while(it != sprite_set.end() && (!checkz || (*it)->total_z() < upto_z))
4564 {
4565 30698 sprite* spr = *it;
4566
2/2
✓ Branch 0 taken 27768 times.
✓ Branch 1 taken 2930 times.
30698 if(spr == &Hero) // Draw the Hero
4567 {
4568 2930 decorations.draw2(dest,true);
4569 2930 Hero.draw(dest);
4570 2930 decorations.draw(dest,true);
4571
4572 // Draw enemies holding the Hero directly above the Hero
4573
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 for(int32_t i=0; i<guys.Count(); i++)
4574 {
4575 if(((enemy*)guys.spr(i))->type == eeWALK)
4576 if(((eStalfos*)guys.spr(i))->hashero)
4577 guys.spr(i)->draw(dest);
4578 else if(((enemy*)guys.spr(i))->type == eeWALLM)
4579 if(((eWallM*)guys.spr(i))->hashero)
4580 guys.spr(i)->draw(dest);
4581 }
4582 2930 }
4583
2/2
✓ Branch 0 taken 24838 times.
✓ Branch 1 taken 2930 times.
27768 else if(spr == &mblock2) // Draw the moving pushblock
4584 {
4585 2930 mblock2.draw(dest, -1);
4586 2930 do_primitives(dest, SPLAYER_MOVINGBLOCK);
4587 2930 }
4588
2/4
✓ Branch 0 taken 24838 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24838 times.
24838 else if(enemy* e = dynamic_cast<enemy*>(spr))
4589 {
4590 e->draw(dest);
4591 e->draw2(dest); // used specifically for eGleeok/esGleeok
4592 }
4593 24838 else spr->draw(dest);
4594 30698 ++it;
4595 }
4596
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4597 clear_clip_rect(dest);
4598 17580 }
4599
4600 15542695 void draw_screen(bool showhero, bool runGeneric)
4601 {
4602 15542695 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
4603 15542695 clear_info_bmp();
4604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15542695 times.
15542695 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4605 {
4606 FFCore.doScriptMenuDraws();
4607 return;
4608 }
4609
4610
2/2
✓ Branch 0 taken 601731 times.
✓ Branch 1 taken 14940964 times.
15542695 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4611
4612 15542695 clear_bitmap(framebuf);
4613 15542695 clear_clip_rect(framebuf);
4614
4615 15542695 int32_t cmby2=0;
4616
4617 // Draw some background layers
4618 15542695 clear_bitmap(scrollbuf);
4619
4620 15542695 auto nearby_screens = get_nearby_screens();
4621
4622
2/2
✓ Branch 0 taken 15539765 times.
✓ Branch 1 taken 2930 times.
15542695 if (!classic_draw)
4623 {
4624
2/2
✓ Branch 0 taken 11720 times.
✓ Branch 1 taken 2930 times.
14650 for (int layer = -7; layer <= -4; ++layer)
4625 {
4626
1/2
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
11720 _do_current_ffc_layer(framebuf, layer);
4627
2/4
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11720 times.
11720 if (script_drawing_commands.is_dirty(layer))
4628 do_primitives(scrollbuf, layer);
4629 11720 }
4630 2930 }
4631
4632 // Handle layer 2/3 possibly being background layers.
4633
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 15539765 times.
15542695 if (classic_draw) // weird ordering (-3 > -2)
4634 {
4635
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4636 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4637
2/2
✓ Branch 0 taken 15548802 times.
✓ Branch 1 taken 127281 times.
15676083 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4638 127281 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4639 15676083 });
4640
4641 15539765 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4642
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 15412484 times.
15539765 if (l2bg)
4643 {
4644
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 do_layer_primitives(scrollbuf, 2);
4645
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 particles.draw(scrollbuf, true, 2);
4646 127281 }
4647
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, -2);
4648
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 15412484 times.
15539765 if (l2bg)
4649
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 draw_msgstr(2, scrollbuf);
4650 15539765 }
4651
4652
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
31221708 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4653 15679013 mapscr* base_scr = screen_handles[0].base_scr;
4654
2/2
✓ Branch 0 taken 15586354 times.
✓ Branch 1 taken 92659 times.
15679013 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4655 92659 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4656 15679013 });
4657
4658
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15450036 times.
15542695 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4659 {
4660
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 do_layer_primitives(scrollbuf, 3);
4661
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 particles.draw(scrollbuf, true, 3);
4662 92659 }
4663
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 _do_current_ffc_layer(scrollbuf, -3);
4664
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15450036 times.
15542695 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4665
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 draw_msgstr(3, scrollbuf);
4666
4667
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 15539765 times.
15542695 if (!classic_draw)
4668 {
4669
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -3);
4670 // Actually use proper ordering (-3 < -2)
4671
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
5860 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4672 2930 mapscr* base_scr = screen_handles[0].base_scr;
4673
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4674 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4675 2930 });
4676
4677 2930 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4678
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4679 {
4680 do_layer_primitives(scrollbuf, 2);
4681 particles.draw(scrollbuf, true, 2);
4682 }
4683
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -2);
4684
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4685 draw_msgstr(2, scrollbuf);
4686
4687
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -2);
4688
4689
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(framebuf, -1);
4690
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -1);
4691 2930 }
4692
4693 // Draw the main combo screens ("layer 0").
4694
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
31221708 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4695 15679013 mapscr* base_scr = screen_handles[0].base_scr;
4696
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15679013 times.
15679013 if (lenscheck(base_scr, 0))
4697 {
4698 15679013 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4699 15679013 }
4700 15679013 });
4701
4702
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15542695 times.
15542695 if (lenscheck(hero_scr, 0))
4703 {
4704
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15076646 times.
15542695 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4705
3/4
✓ Branch 0 taken 466049 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 461913 times.
470185 if(mblock2.draw(scrollbuf,0))
4706
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4707 15542695 }
4708
4709 // Lens hints, then primitives, then particles.
4710
6/10
✓ Branch 0 taken 15532666 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15532666 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15532666 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
15542695 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4711 {
4712
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4713
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4714 5876 }
4715
4716
2/4
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15542695 times.
✗ Branch 3 not taken.
15542695 if(show_layers[0] && lenscheck(hero_scr,0))
4717
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 do_primitives(scrollbuf, 0);
4718
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 particles.draw(scrollbuf, true, 0);
4719
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 _do_current_ffc_layer(scrollbuf, 0);
4720
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 draw_msgstr(0, scrollbuf);
4721
4722
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 set_draw_screen_clip(scrollbuf);
4723
4724 15542695 bool hero_draw_done = false;
4725
4/6
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15507943 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 15507943 times.
✗ Branch 5 not taken.
15542695 bool is_cave_walking = ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom));
4726
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15199436 times.
15542695 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4727 {
4728
4/4
✓ Branch 0 taken 15197562 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 15109178 times.
15199436 if(showhero && is_cave_walking)
4729 {
4730 88384 hero_draw_done = true;
4731
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4732 {
4733 34752 cmby2=16;
4734 34752 }
4735
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4736 {
4737 53632 cmby2=-16;
4738 53632 }
4739
4740
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4741
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4742
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4743
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4744
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4745
4746
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4747
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4748
4749
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4750 {
4751
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4752
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4753 15232 }
4754 88384 }
4755 15199436 }
4756
4757
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 15542695 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15542695 if (get_qr(qr_HERO_DIVE_UNDER_LAYER_1) && Hero.isDiving())
4758 {
4759 Hero.draw_under(scrollbuf);
4760 decorations.draw2(scrollbuf,true);
4761 Hero.draw(scrollbuf);
4762 decorations.draw(scrollbuf,true);
4763 hero_draw_done = true;
4764 }
4765
4766
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
31221708 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4767 15679013 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4768 15679013 });
4769
4770
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 do_layer_primitives(scrollbuf, 1);
4771
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 particles.draw(scrollbuf, true, 1);
4772
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 _do_current_ffc_layer(scrollbuf, 1);
4773
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 draw_msgstr(1, scrollbuf);
4774
4775 // Handle layer 2 NOT being used as background layers.
4776
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
31221708 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4777 15679013 mapscr* base_scr = screen_handles[0].base_scr;
4778
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 15551732 times.
15679013 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4779 15551732 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4780 15679013 });
4781
4782
2/2
✓ Branch 0 taken 15415414 times.
✓ Branch 1 taken 127281 times.
15542695 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4783 {
4784
1/2
✓ Branch 0 taken 15415414 times.
✗ Branch 1 not taken.
15415414 do_layer_primitives(scrollbuf, 2);
4785
1/2
✓ Branch 0 taken 15415414 times.
✗ Branch 1 not taken.
15415414 particles.draw(scrollbuf, true, 2);
4786 15415414 }
4787
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 _do_current_ffc_layer(scrollbuf, 2);
4788
2/2
✓ Branch 0 taken 15415414 times.
✓ Branch 1 taken 127281 times.
15542695 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4789
1/2
✓ Branch 0 taken 15415414 times.
✗ Branch 1 not taken.
15415414 draw_msgstr(2, scrollbuf);
4790
4791
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4792
4793
2/2
✓ Branch 0 taken 15199436 times.
✓ Branch 1 taken 343259 times.
15542695 if(get_qr(qr_LAYER12UNDERCAVE))
4794 {
4795
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
343259 if(showhero && is_cave_walking)
4796 {
4797 hero_draw_done = true;
4798 if(Hero.getAction()==climbcovertop)
4799 {
4800 cmby2=16;
4801 }
4802 else if(Hero.getAction()==climbcoverbottom)
4803 {
4804 cmby2=-16;
4805 }
4806
4807 decorations.draw2(scrollbuf,true);
4808 Hero.draw(scrollbuf);
4809 decorations.draw(scrollbuf,true);
4810 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4811 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4812
4813 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4814 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4815
4816 if(int32_t(Hero.getX())&15)
4817 {
4818 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4819 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4820 }
4821 }
4822 343259 }
4823
4824
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15076646 times.
15542695 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4825 {
4826
1/2
✓ Branch 0 taken 15076646 times.
✗ Branch 1 not taken.
30289610 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4827 15212964 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4828
2/2
✓ Branch 0 taken 14478915 times.
✓ Branch 1 taken 734049 times.
15212964 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4829 {
4830 734049 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4831 734049 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4832 734049 }
4833 15212964 });
4834
4835
1/2
✓ Branch 0 taken 15076646 times.
✗ Branch 1 not taken.
15076646 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4836 15076646 }
4837
4838 // Show walkflags cheat
4839
2/4
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15542695 times.
15542695 if (show_walkflags || show_effectflags)
4840 {
4841 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4842 do_walkflags(screen_handles, offx, offy);
4843 do_effectflags(screen_handles[0].base_scr, offx, offy);
4844 });
4845
4846 do_walkflags(0, 0);
4847 }
4848
4849
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4850
4851 // Lens hints, doors etc.
4852
4/8
✓ Branch 0 taken 15532666 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15532666 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15532666 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
15542695 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4853 {
4854
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4855 {
4856
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4857
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4858 4153 }
4859
4860
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4861
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4862 10029 }
4863
4864 // Blit those layers onto framebuf
4865
4866
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 set_draw_screen_clip(framebuf);
4867
4868
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 blit(scrollbuf, framebuf, 0, 0, 0, 0, 256, 232);
4869
4870 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4871 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4872
4873 // Draw the subscreen, without clipping
4874
2/2
✓ Branch 0 taken 9251384 times.
✓ Branch 1 taken 6291311 times.
15542695 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4875 {
4876 9251384 bool dotime = false;
4877
4/6
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412853 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412853 times.
✗ Branch 5 not taken.
9251384 if (replay_version_check(22)) dotime = game->should_show_time();
4878
1/2
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
9251384 put_passive_subscr(framebuf, 0, 0, dotime, sspUP);
4879 9251384 }
4880
4881 // Draw some sprites onto framebuf
4882
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 set_clip_rect(framebuf,0,0,256,232);
4883
4884
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 15443199 times.
15542695 if(!(pricesdisplaybuf->clip))
4885 {
4886
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,framebuf,0,0,0,playing_field_offset,256,176);
4887 99496 }
4888
4889
5/6
✓ Branch 0 taken 15497069 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15490741 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15542695 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4890 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4891
4892
4/4
✓ Branch 0 taken 15540821 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15452437 times.
✓ Branch 3 taken 88384 times.
15542695 if(showhero && !hero_draw_done)
4893 {
4894
1/2
✓ Branch 0 taken 15452437 times.
✗ Branch 1 not taken.
15452437 Hero.draw_under(framebuf);
4895
4896
3/4
✓ Branch 0 taken 15452437 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15311052 times.
15452437 if(Hero.isSwimming())
4897 {
4898
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(framebuf,true);
4899
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(framebuf);
4900
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(framebuf,true);
4901 141385 hero_draw_done = true;
4902 141385 }
4903 15452437 }
4904
4905 15542695 set<sprite*, SpriteSorter> sorted_sprites;
4906 15542695 vector<sprite*> temp_sprites;
4907 15542695 std::function<bool(sprite&)> add_sprite = [&](sprite& spr)
4908 {
4909 sorted_sprites.insert(&spr);
4910 return false;
4911 };
4912
4913
2/2
✓ Branch 0 taken 15539765 times.
✓ Branch 1 taken 2930 times.
15542695 if (classic_draw)
4914 {
4915
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 15513670 times.
15539765 if(drawguys)
4916 {
4917
4/4
✓ Branch 0 taken 1982674 times.
✓ Branch 1 taken 13530996 times.
✓ Branch 2 taken 991089 times.
✓ Branch 3 taken 991585 times.
15513670 if(get_qr(qr_NOFLICKER) || (frame&1))
4918 {
4919 // Just clips sprites if in a repeating, smooth maze.
4920
2/2
✓ Branch 0 taken 14512871 times.
✓ Branch 1 taken 9214 times.
14522085 bool do_clip = maze_state.active && maze_state.loopy;
4921
4922
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 if(!get_qr(qr_OLD_WEAPON_DRAW_ANIMATE_TIMING))
4923 {
4924 if (do_clip)
4925 {
4926 Ewpns.drawshadow_smooth_maze(framebuf,get_qr(qr_TRANSSHADOWS));
4927 Lwpns.drawshadow_smooth_maze(framebuf,get_qr(qr_TRANSSHADOWS));
4928 }
4929 else
4930 {
4931 Ewpns.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS),true);
4932 Lwpns.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS),true);
4933 }
4934 }
4935
3/4
✓ Branch 0 taken 23627227 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9105142 times.
✓ Branch 3 taken 14522085 times.
23627227 for(int32_t i=0; i<Ewpns.Count(); i++)
4936 {
4937
3/4
✓ Branch 0 taken 9105142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✓ Branch 3 taken 8907199 times.
9105142 if(((weapon *)Ewpns.spr(i))->behind)
4938
2/4
✓ Branch 0 taken 197943 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✗ Branch 3 not taken.
197943 Ewpns.spr(i)->draw(framebuf);
4939 9105142 }
4940
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4941
4942
3/4
✓ Branch 0 taken 19197181 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4675096 times.
✓ Branch 3 taken 14522085 times.
19197181 for(int32_t i=0; i<Lwpns.Count(); i++)
4943 {
4944
3/4
✓ Branch 0 taken 4675096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✓ Branch 3 taken 4671891 times.
4675096 if(((weapon *)Lwpns.spr(i))->behind)
4945
2/4
✓ Branch 0 taken 3205 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✗ Branch 3 not taken.
3205 Lwpns.spr(i)->draw(framebuf);
4946 4675096 }
4947
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4948
4949
6/6
✓ Branch 0 taken 9785221 times.
✓ Branch 1 taken 4736864 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 8436921 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
14522085 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4950 {
4951
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9107274 times.
9110932 if (do_clip)
4952
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4953 else
4954
1/2
✓ Branch 0 taken 9107274 times.
✗ Branch 1 not taken.
9107274 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4955 9110932 }
4956
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4957
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(framebuf);
4958 else
4959
1/2
✓ Branch 0 taken 14518427 times.
✗ Branch 1 not taken.
14518427 guys.draw(framebuf,true);
4960
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4961 {
4962 3658 int maze_screen = maze_state.scr->screen;
4963
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4964
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4965 3658 }
4966
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4967
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4968
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4969
4970
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 chainlinks.draw(framebuf,true);
4971
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4972 //Lwpns.draw(framebuf,true);
4973
4974
3/4
✓ Branch 0 taken 23627227 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9105142 times.
✓ Branch 3 taken 14522085 times.
23627227 for(int32_t i=0; i<Ewpns.Count(); i++)
4975 {
4976
3/4
✓ Branch 0 taken 9105142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8907199 times.
✓ Branch 3 taken 197943 times.
9105142 if(!((weapon *)Ewpns.spr(i))->behind)
4977
2/4
✓ Branch 0 taken 8907199 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8907199 times.
✗ Branch 3 not taken.
8907199 Ewpns.spr(i)->draw(framebuf);
4978 9105142 }
4979
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4980
4981
3/4
✓ Branch 0 taken 19197181 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4675096 times.
✓ Branch 3 taken 14522085 times.
19197181 for(int32_t i=0; i<Lwpns.Count(); i++)
4982 {
4983
3/4
✓ Branch 0 taken 4675096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4671891 times.
✓ Branch 3 taken 3205 times.
4675096 if(!((weapon *)Lwpns.spr(i))->behind)
4984
2/4
✓ Branch 0 taken 4671891 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4671891 times.
✗ Branch 3 not taken.
4671891 Lwpns.spr(i)->draw(framebuf);
4985 4675096 }
4986
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4987
4988
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4989
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(framebuf);
4990 else
4991
1/2
✓ Branch 0 taken 14518427 times.
✗ Branch 1 not taken.
14518427 items.draw(framebuf,true);
4992
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4993 {
4994 3658 int maze_screen = maze_state.scr->screen;
4995
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4996
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4997 3658 }
4998
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4999
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
5000
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
5001 14522085 }
5002 else
5003 {
5004
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
5005 {
5006
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
5007
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(framebuf);
5008 505372 }
5009
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
5010
5011
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
5012 {
5013
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 231146 times.
231146 if(((weapon *)Lwpns.spr(i))->behind)
5014 Lwpns.spr(i)->draw(framebuf);
5015 231146 }
5016
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
5017
5018
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991585 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5019 {
5020
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
5021 228620 }
5022
5023
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 items.draw(framebuf,false);
5024
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
5025
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 chainlinks.draw(framebuf,false);
5026
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
5027 //Lwpns.draw(framebuf,false);
5028
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 guys.draw(framebuf,false);
5029
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_NPC_DRAW);
5030
5031
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
5032 {
5033
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
5034 {
5035
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(framebuf);
5036 496727 }
5037 505372 }
5038
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
5039
5040
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
5041 {
5042
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 if(!((weapon *)Lwpns.spr(i))->behind)
5043 {
5044
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 Lwpns.spr(i)->draw(framebuf);
5045 231146 }
5046 231146 }
5047
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
5048 }
5049
5050
1/2
✓ Branch 0 taken 15513670 times.
✗ Branch 1 not taken.
15513670 guys.draw2(framebuf,true);
5051 15513670 }
5052
5053
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if(mirror_portal.destdmap > -1)
5054 mirror_portal.draw(framebuf);
5055
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 portals.draw(framebuf,true);
5056
5057
4/4
✓ Branch 0 taken 15537891 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 15449507 times.
15539765 if(showhero && !is_cave_walking)
5058 {
5059
2/2
✓ Branch 0 taken 14989874 times.
✓ Branch 1 taken 459633 times.
15449507 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5060 {
5061
1/2
✓ Branch 0 taken 14989874 times.
✗ Branch 1 not taken.
14989874 mblock2.draw(framebuf,-1);
5062
1/2
✓ Branch 0 taken 14989874 times.
✗ Branch 1 not taken.
14989874 do_primitives(framebuf, SPLAYER_MOVINGBLOCK);
5063 14989874 }
5064
2/2
✓ Branch 0 taken 15308122 times.
✓ Branch 1 taken 141385 times.
15449507 if(!hero_draw_done)
5065 {
5066
8/12
✓ Branch 0 taken 15308122 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15308122 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15288952 times.
✓ Branch 5 taken 19170 times.
✓ Branch 6 taken 15288952 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15288952 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15306752 times.
15308122 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5067 {
5068
2/2
✓ Branch 0 taken 18485 times.
✓ Branch 1 taken 15289637 times.
15308122 Hero.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
5069 18485 }
5070
5071
6/8
✓ Branch 0 taken 15308122 times.
✓ Branch 1 taken 15289637 times.
✓ Branch 2 taken 15308122 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15308122 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15294058 times.
✓ Branch 7 taken 14064 times.
18485 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
5072 {
5073
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 decorations.draw2(framebuf,true);
5074
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 Hero.draw(framebuf);
5075
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 decorations.draw(framebuf,true);
5076 15294058 hero_draw_done = true;
5077 15294058 }
5078 15308122 }
5079 15449507 }
5080
5081
3/4
✓ Branch 0 taken 54880218 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39340453 times.
✓ Branch 3 taken 15539765 times.
54880218 for(int32_t i=0; i<guys.Count(); i++)
5082 {
5083
3/4
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15945464 times.
✓ Branch 3 taken 23394989 times.
39340453 if(((enemy*)guys.spr(i))->type == eeWALK)
5084 {
5085
3/4
✓ Branch 0 taken 15945464 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✓ Branch 3 taken 15938169 times.
15945464 if(((eStalfos*)guys.spr(i))->hashero)
5086 {
5087
2/4
✓ Branch 0 taken 7295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✗ Branch 3 not taken.
7295 guys.spr(i)->draw(framebuf);
5088 7295 }
5089 15945464 }
5090
5091
3/4
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 38833291 times.
39340453 if(((enemy*)guys.spr(i))->type == eeWALLM)
5092 {
5093
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
5094 {
5095
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(framebuf);
5096 1329 }
5097 507162 }
5098
5099
11/20
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39340453 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39340453 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 39340453 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 39340453 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 39340453 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 39340453 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 39340453 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 39340453 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1342694 times.
✓ Branch 19 taken 37997759 times.
39340453 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
5100 {
5101 //Jumping enemies in front of Hero.
5102
2/4
✓ Branch 0 taken 1342694 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1342694 times.
✗ Branch 3 not taken.
1342694 guys.spr(i)->draw(framebuf);
5103 1342694 }
5104
1/2
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
39340453 do_primitives(framebuf, SPLAYER_NPC_ABOVEPLAYER_DRAW);
5105 39340453 }
5106 15539765 }
5107 else
5108 {
5109
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(drawguys)
5110 {
5111
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 chainlinks.forEach(add_sprite);
5112
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
5860 bool show_enemy_shadows = (get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1));
5113 25837 auto add_spr_shadow = [&](sprite& spr)
5114 {
5115 22907 sorted_sprites.insert(&spr);
5116
3/4
✓ Branch 0 taken 1291 times.
✓ Branch 1 taken 21616 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1291 times.
22907 if(spr.total_z() > 0 && spr.can_drawshadow())
5117 {
5118
1/2
✓ Branch 0 taken 1291 times.
✗ Branch 1 not taken.
1291 tempsprite_shadow* shadow = new tempsprite_shadow(&spr);
5119 1291 sorted_sprites.insert(shadow);
5120 1291 temp_sprites.push_back(shadow);
5121 1291 }
5122 22907 return false;
5123 };
5124
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Lwpns.forEach(add_spr_shadow);
5125
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Ewpns.forEach(add_spr_shadow);
5126
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 items.forEach(add_spr_shadow);
5127
4/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2930 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2930 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2930 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2930 guys.forEach(show_enemy_shadows ? add_spr_shadow : add_sprite);
5128 2930 }
5129
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 if(showhero && !hero_draw_done)
5130 {
5131
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&Hero);
5132
9/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2290 times.
✓ Branch 5 taken 640 times.
✓ Branch 6 taken 2290 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2290 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2930 times.
✓ Branch 12 taken 2290 times.
✓ Branch 13 taken 2290 times.
2930 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5133 {
5134
3/4
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 4580 times.
✓ Branch 2 taken 640 times.
✗ Branch 3 not taken.
5220 tempsprite_shadow* shadow = new tempsprite_shadow(&Hero);
5135
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 sorted_sprites.insert(shadow);
5136
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 temp_sprites.push_back(shadow);
5137 640 }
5138 2930 }
5139
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if(mirror_portal.destdmap > -1)
5140 sorted_sprites.insert(&mirror_portal);
5141
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 portals.forEach(add_sprite);
5142
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5143
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&mblock2);
5144 }
5145 15542695 auto sprite_it = sorted_sprites.begin();
5146
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 15539765 times.
15542695 if (!classic_draw)
5147
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(framebuf, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_GROUND]);
5148
5149 // Draw some layers onto framebuf
5150
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 set_draw_screen_clip(framebuf);
5151
5/6
✓ Branch 0 taken 15497069 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15490741 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15542695 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5152 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5153
5154 // Handle layer 3 NOT being used as background layers.
5155
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
31221708 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5156 15679013 mapscr* base_scr = screen_handles[0].base_scr;
5157
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15586354 times.
15679013 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5158 15586354 do_layer(framebuf, 0, screen_handles[3], offx, offy);
5159 15679013 });
5160
5161
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 15539765 times.
15542695 if (!classic_draw)
5162
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(framebuf, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_3]);
5163
5164
2/2
✓ Branch 0 taken 15450036 times.
✓ Branch 1 taken 92659 times.
15542695 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5165 {
5166
1/2
✓ Branch 0 taken 15450036 times.
✗ Branch 1 not taken.
15450036 do_layer_primitives(framebuf, 3);
5167
1/2
✓ Branch 0 taken 15450036 times.
✗ Branch 1 not taken.
15450036 particles.draw(framebuf, true, 3);
5168 15450036 }
5169
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 _do_current_ffc_layer(framebuf, 3);
5170
2/2
✓ Branch 0 taken 15450036 times.
✓ Branch 1 taken 92659 times.
15542695 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5171
1/2
✓ Branch 0 taken 15450036 times.
✗ Branch 1 not taken.
15450036 draw_msgstr(3);
5172
5173
5174
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
31221708 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5175 15679013 do_layer(framebuf, 0, screen_handles[4], offx, offy);
5176 15679013 });
5177
5178
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 15539765 times.
15542695 if (!classic_draw)
5179
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(framebuf, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_4]);
5180
5181
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 do_layer_primitives(framebuf, 4);
5182
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 particles.draw(framebuf, true, 4);
5183
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 _do_current_ffc_layer(framebuf, 4);
5184
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 draw_msgstr(4);
5185
5186
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
31221708 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5187 15679013 do_layer(framebuf, -1, screen_handles[0], offx, offy);
5188
2/2
✓ Branch 0 taken 14400195 times.
✓ Branch 1 taken 1278818 times.
15679013 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
5189 {
5190 1278818 do_layer(framebuf, -1, screen_handles[1], offx, offy);
5191 1278818 do_layer(framebuf, -1, screen_handles[2], offx, offy);
5192 1278818 }
5193 15679013 });
5194
5195
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 do_primitives(framebuf, SPLAYER_OVERHEAD_CMB);
5196
5197 // Draw some flying sprites onto framebuf
5198
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 clear_clip_rect(framebuf);
5199
5/6
✓ Branch 0 taken 15497069 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15490741 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15542695 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5200 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5201
5202
2/2
✓ Branch 0 taken 15539765 times.
✓ Branch 1 taken 2930 times.
15542695 if (classic_draw)
5203 {
5204 //Jumping Hero and jumping enemies are drawn on this layer.
5205
5/8
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15539765 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15539765 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14064 times.
✓ Branch 7 taken 15525701 times.
15539765 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
5206 {
5207
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw2(framebuf,false);
5208
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 Hero.draw(framebuf);
5209
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 chainlinks.draw(framebuf,true);
5210
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
5211
5212
3/4
✓ Branch 0 taken 16806 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14064 times.
16806 for(int32_t i=0; i<Lwpns.Count(); i++)
5213 {
5214
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
5215 {
5216
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(framebuf);
5217 239 }
5218 2742 }
5219
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(framebuf, SPLAYER_LWEAP_ABOVE_DRAW);
5220
5221
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw(framebuf,false);
5222 14064 }
5223
5224
5/6
✓ Branch 0 taken 3288981 times.
✓ Branch 1 taken 12250784 times.
✓ Branch 2 taken 44334375 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32083591 times.
✓ Branch 5 taken 12250784 times.
47623356 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
5225 {
5226
13/22
✓ Branch 0 taken 32083591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32083591 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27177493 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27177493 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27177493 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27177493 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27177493 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27177493 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27177493 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27177493 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27170925 times.
32083591 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
5227 {
5228
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(framebuf);
5229 4912666 }
5230 44334375 }
5231 else
5232 {
5233
3/4
✓ Branch 0 taken 10545843 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✓ Branch 3 taken 3288981 times.
10545843 for(int32_t i=0; i<guys.Count(); i++)
5234 {
5235
13/22
✓ Branch 0 taken 7256862 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6081157 times.
✓ Branch 5 taken 1175705 times.
✓ Branch 6 taken 6081157 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6081157 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6081157 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5594346 times.
✓ Branch 13 taken 486811 times.
✓ Branch 14 taken 5594346 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 5594346 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 5594346 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 5594346 times.
7256862 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
5236 {
5237
2/4
✓ Branch 0 taken 1662516 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1662516 times.
✗ Branch 3 not taken.
1662516 guys.spr(i)->draw(framebuf);
5238 1662516 }
5239 7256862 }
5240 }
5241
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_NPC_AIRBORNE_DRAW);
5242 15539765 }
5243
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 else draw_sprites(framebuf, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_OVERHEAD]);
5244
5245 // Draw the Moving Fairy above layer 3
5246
3/4
✓ Branch 0 taken 18689081 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3146386 times.
✓ Branch 3 taken 15542695 times.
18689081 for(int32_t i=0; i<items.Count(); i++)
5247
6/8
✓ Branch 0 taken 3146386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69867 times.
✓ Branch 3 taken 3076519 times.
✓ Branch 4 taken 69867 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60153 times.
✓ Branch 7 taken 9714 times.
3206539 if(itemsbuf[items.spr(i)->id].type == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
5248
2/4
✓ Branch 0 taken 60153 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60153 times.
✗ Branch 3 not taken.
60153 items.spr(i)->draw(framebuf);
5249
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 do_primitives(framebuf, SPLAYER_FAIRYITEM_DRAW);
5250
5251 // Draw some layers onto framebuf
5252
5253
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 set_draw_screen_clip(framebuf);
5254
5255
2/2
✓ Branch 0 taken 15528343 times.
✓ Branch 1 taken 14352 times.
15542695 if (lightbeam_present)
5256 {
5257 14352 color_map = &trans_table2;
5258
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5259
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(framebuf, lightbeam_bmp, 0, playing_field_offset);
5260 else
5261
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, framebuf, 0, 0, 0, playing_field_offset, 256, 176);
5262 14352 color_map = &trans_table;
5263 14352 }
5264
5265
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
31221708 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5266 15679013 do_layer(framebuf, 0, screen_handles[5], offx, offy);
5267 15679013 });
5268
5269
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 15539765 times.
15542695 if (!classic_draw)
5270
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(framebuf, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_5]);
5271
5272
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 do_layer_primitives(framebuf, 5);
5273
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 particles.draw(framebuf, true, 5);
5274
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 _do_current_ffc_layer(framebuf, 5);
5275
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 draw_msgstr(5);
5276
5277
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 _do_current_ffc_layer(framebuf, -1000); // 'overhead' freeform combos
5278
5279
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 do_primitives(framebuf, SPLAYER_OVERHEAD_FFC);
5280
5281
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
31221708 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5282 15679013 do_layer(framebuf, 0, screen_handles[6], offx, offy);
5283 15679013 });
5284
5285
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 15539765 times.
15542695 if (!classic_draw)
5286
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(framebuf, sorted_sprites, sprite_it, word(-1));
5287
5288
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 do_layer_primitives(framebuf, 6);
5289
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 particles.draw(framebuf, true, 6);
5290
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 _do_current_ffc_layer(framebuf, 6);
5291
5292 15542695 bool any_dark = false;
5293
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
31221708 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5294 15679013 mapscr* base_scr = screen_handles[0].scr;
5295 15679013 any_dark |= is_dark(base_scr);
5296 15679013 });
5297
5298 // Handle low drawn darkness
5299
4/4
✓ Branch 0 taken 1272482 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1028711 times.
✓ Branch 3 taken 243771 times.
15542695 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5300 {
5301
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5302 250005 mapscr* base_scr = screen_handles[0].scr;
5303 250005 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5304 250005 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5305 250005 });
5306
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 if(showhero)
5307
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 Hero.calc_darkroom_hero(0, -playing_field_offset);
5308
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5309 250005 mapscr* base_scr = screen_handles[0].scr;
5310
2/2
✓ Branch 0 taken 245275 times.
✓ Branch 1 taken 4730 times.
250005 if (!is_dark(base_scr))
5311 {
5312 4730 offy += playing_field_offset;
5313 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5314 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5315 4730 }
5316 250005 });
5317 243771 }
5318
5319 //Darkroom if under the subscreen
5320
6/6
✓ Branch 0 taken 1272482 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 823284 times.
✓ Branch 3 taken 449198 times.
✓ Branch 4 taken 231780 times.
✓ Branch 5 taken 591504 times.
15542695 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5321 {
5322
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5323
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231780 times.
231780 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5325 {
5326 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5327 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5328 }
5329
5330 231780 color_map = &trans_table2;
5331
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 231636 times.
231780 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5332 {
5333
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5334
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5335
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5336 144 }
5337 else
5338 {
5339
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5340
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5341 }
5342 231780 color_map = &trans_table;
5343
5344
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5345
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5346 231780 }
5347
5348
3/6
✓ Branch 0 taken 45626 times.
✓ Branch 1 taken 15497069 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45626 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15542695 if (is_extended_height_mode() && lensclk && !FFCore.system_suspend[susptLENS])
5349 {
5350 draw_lens_over();
5351 --lensclk;
5352 }
5353
5354 // Draw some text on framebuf
5355
5356
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 set_clip_rect(framebuf,0,0,256,232);
5357
5358
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5359
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 draw_msgstr(6);
5360
5361 // Draw the subscreen, without clipping
5362
2/2
✓ Branch 0 taken 6291311 times.
✓ Branch 1 taken 9251384 times.
15542695 if(get_qr(qr_SUBSCREENOVERSPRITES))
5363 {
5364
2/4
✓ Branch 0 taken 6291311 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6291311 times.
✗ Branch 3 not taken.
6291311 put_passive_subscr(framebuf, 0, 0, game->should_show_time(), sspUP);
5365
1/2
✓ Branch 0 taken 6291311 times.
✗ Branch 1 not taken.
6291311 do_primitives(framebuf, 7);
5366 6291311 }
5367
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9251384 times.
9251384 else if (!classic_draw)
5368 do_primitives(framebuf, 7);
5369
5370
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15542695 times.
15542695 if(get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5371 draw_msgstr(6);
5372
5373 // Handle high-drawn darkness
5374
6/6
✓ Branch 0 taken 1272482 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 449198 times.
✓ Branch 3 taken 823284 times.
✓ Branch 4 taken 11991 times.
✓ Branch 5 taken 437207 times.
15542695 if(get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
5375 {
5376
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5377
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5379 {
5380 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5381 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5382 }
5383
5384 11991 color_map = &trans_table2;
5385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5386 {
5387 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5388 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5389 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5390 }
5391 else
5392 {
5393
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5394
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5395 }
5396 11991 color_map = &trans_table;
5397
5398
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5399
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5400 11991 }
5401
5402
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 _do_current_ffc_layer(framebuf, 7);
5403
1/2
✓ Branch 0 taken 15542695 times.
✗ Branch 1 not taken.
15542695 draw_msgstr(7);
5404
5405
2/2
✓ Branch 0 taken 15041159 times.
✓ Branch 1 taken 30583854 times.
15542695 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5406
3/4
✓ Branch 0 taken 14940964 times.
✓ Branch 1 taken 120639 times.
✓ Branch 2 taken 14940964 times.
✗ Branch 3 not taken.
15041159 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5407
5408
2/2
✓ Branch 0 taken 1931 times.
✓ Branch 1 taken 15061603 times.
15063534 for(sprite* spr : temp_sprites)
5409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1931 times.
1931 delete spr;
5410 76229311 }
5411
5412 // TODO: separate setting door data and drawing door
5413 28153 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5414 {
5415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28153 times.
28153 if (type > 8) return;
5416
5417 28153 int32_t d=scr->door_combo_set;
5418
5419
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12542 times.
28153 switch(type)
5420 {
5421 case dt_wall:
5422 case dt_walk:
5423 if(!even_walls)
5424 break;
5425 [[fallthrough]];
5426 case dt_pass:
5427
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12542 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5428 1036 break;
5429 [[fallthrough]];
5430 case dt_lock:
5431 case dt_shut:
5432 case dt_boss:
5433 case dt_olck:
5434 case dt_osht:
5435 case dt_obos:
5436 case dt_bomb:
5437
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5438 {
5439 case up:
5440 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5441 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5442 7259 scr->sflag[pos] = 0;
5443 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5444 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5445 7259 scr->sflag[pos+1] = 0;
5446 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5447 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5448 7259 scr->sflag[pos+16] = 0;
5449 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5450 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5451 7259 scr->sflag[pos+16+1] = 0;
5452
5453
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5454 {
5455 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5456 1824 DoorComboSets[d].doorcombo_u[type][0],
5457 1824 DoorComboSets[d].doorcset_u[type][0]);
5458 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5459 1824 DoorComboSets[d].doorcombo_u[type][1],
5460 1824 DoorComboSets[d].doorcset_u[type][1]);
5461 1824 }
5462
5463 7259 break;
5464
5465 case down:
5466 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5467 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5468 6784 scr->sflag[pos] = 0;
5469 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5470 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5471 6784 scr->sflag[pos+1] = 0;
5472 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5473 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5474 6784 scr->sflag[pos+16] = 0;
5475 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5476 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5477 6784 scr->sflag[pos+16+1] = 0;
5478
5479
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5480 {
5481 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5482 1321 DoorComboSets[d].doorcombo_d[type][2],
5483 1321 DoorComboSets[d].doorcset_d[type][2]);
5484 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5485 1321 DoorComboSets[d].doorcombo_d[type][3],
5486 1321 DoorComboSets[d].doorcset_d[type][3]);
5487 1321 }
5488
5489 6784 break;
5490
5491 case left:
5492 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5493 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5494 6362 scr->sflag[pos] = 0;
5495 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5496 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5497 6362 scr->sflag[pos+1] = 0;
5498 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5499 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5500 6362 scr->sflag[pos+16] = 0;
5501 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5502 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5503 6362 scr->sflag[pos+16+1] = 0;
5504 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5505 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5506 6362 scr->sflag[pos+32] = 0;
5507 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5508 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5509 6362 scr->sflag[pos+32+1] = 0;
5510
5511
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5512 {
5513 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5514 1489 DoorComboSets[d].doorcombo_l[type][0],
5515 1489 DoorComboSets[d].doorcset_l[type][0]);
5516 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5517 1489 DoorComboSets[d].doorcombo_l[type][2],
5518 1489 DoorComboSets[d].doorcset_l[type][2]);
5519 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5520 1489 DoorComboSets[d].doorcombo_l[type][4],
5521 1489 DoorComboSets[d].doorcset_l[type][4]);
5522 1489 }
5523
5524 6362 break;
5525
5526 case right:
5527 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5528 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5529 6712 scr->sflag[pos] = 0;
5530 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5531 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5532 6712 scr->sflag[pos+1] = 0;
5533 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5534 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5535 6712 scr->sflag[pos+16] = 0;
5536 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5537 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5538 6712 scr->sflag[pos+16+1] = 0;
5539 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5540 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5541 6712 scr->sflag[pos+32] = 0;
5542 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5543 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5544 6712 scr->sflag[pos+32+1] = 0;
5545
5546
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5547 {
5548 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5549 1654 DoorComboSets[d].doorcombo_r[type][0],
5550 1654 DoorComboSets[d].doorcset_r[type][0]);
5551 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5552 1654 DoorComboSets[d].doorcombo_r[type][2],
5553 1654 DoorComboSets[d].doorcset_r[type][2]);
5554 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5555 1654 DoorComboSets[d].doorcombo_r[type][4],
5556 1654 DoorComboSets[d].doorcset_r[type][4]);
5557 1654 }
5558
5559 6712 break;
5560 }
5561
5562 27117 break;
5563
5564 default:
5565 break;
5566 }
5567 28153 }
5568
5569 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5570 {
5571 706556 int32_t door_combo_set = scr->door_combo_set;
5572 706556 int32_t x = (pos&15)<<4;
5573 706556 int32_t y = (pos&0xF0);
5574 706556 int32_t d = door_combo_set;
5575 706556 x += offx;
5576 706556 y += offy;
5577
5578
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5579 {
5580 case up:
5581 322272 overcombo2(dest,x,y,
5582 161136 DoorComboSets[d].bombdoorcombo_u[0],
5583 161136 DoorComboSets[d].bombdoorcset_u[0]);
5584 322272 overcombo2(dest,x+16,y,
5585 161136 DoorComboSets[d].bombdoorcombo_u[1],
5586 161136 DoorComboSets[d].bombdoorcset_u[1]);
5587 161136 break;
5588
5589 case down:
5590 359286 overcombo2(dest,x,y,
5591 179643 DoorComboSets[d].bombdoorcombo_d[0],
5592 179643 DoorComboSets[d].bombdoorcset_d[0]);
5593 359286 overcombo2(dest,x+16,y,
5594 179643 DoorComboSets[d].bombdoorcombo_d[1],
5595 179643 DoorComboSets[d].bombdoorcset_d[1]);
5596 179643 break;
5597
5598 case left:
5599 392706 overcombo2(dest,x,y,
5600 196353 DoorComboSets[d].bombdoorcombo_l[0],
5601 196353 DoorComboSets[d].bombdoorcset_l[0]);
5602 392706 overcombo2(dest,x,y+16,
5603 196353 DoorComboSets[d].bombdoorcombo_l[1],
5604 196353 DoorComboSets[d].bombdoorcset_l[1]);
5605 392706 overcombo2(dest,x,y+16,
5606 196353 DoorComboSets[d].bombdoorcombo_l[2],
5607 196353 DoorComboSets[d].bombdoorcset_l[2]);
5608 196353 break;
5609
5610 case right:
5611 338848 overcombo2(dest,x,y,
5612 169424 DoorComboSets[d].bombdoorcombo_r[0],
5613 169424 DoorComboSets[d].bombdoorcset_r[0]);
5614 338848 overcombo2(dest,x,y+16,
5615 169424 DoorComboSets[d].bombdoorcombo_r[1],
5616 169424 DoorComboSets[d].bombdoorcset_r[1]);
5617 338848 overcombo2(dest,x,y+16,
5618 169424 DoorComboSets[d].bombdoorcombo_r[2],
5619 169424 DoorComboSets[d].bombdoorcset_r[2]);
5620 169424 break;
5621 }
5622 706556 }
5623
5624 47568 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5625 {
5626
7/8
✓ Branch 0 taken 47460 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22925 times.
✓ Branch 5 taken 24535 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22395 times.
47568 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5627 25173 return;
5628
5629 int32_t doortype;
5630
5631
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12492 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22395 switch(door)
5632 {
5633 case dWALL:
5634 doortype=dt_wall;
5635 break;
5636
5637 case dWALK:
5638 doortype=dt_walk;
5639 break;
5640
5641 case dOPEN:
5642 12492 doortype=dt_pass;
5643 12492 break;
5644
5645 case dLOCKED:
5646 910 doortype=dt_lock;
5647 910 break;
5648
5649 case dUNLOCKED:
5650 1553 doortype=dt_olck;
5651 1553 break;
5652
5653 case dSHUTTER:
5654
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5655 {
5656 doortype=dt_osht;
5657 get_screen_state(scr->screen).open_doors = -4;
5658 break;
5659 }
5660
5661 [[fallthrough]];
5662 case d1WAYSHUTTER:
5663 3714 doortype=dt_shut;
5664 3714 break;
5665
5666 case dOPENSHUTTER:
5667 1694 doortype=dt_osht;
5668 1694 break;
5669
5670 case dBOSS:
5671 172 doortype=dt_boss;
5672 172 break;
5673
5674 case dOPENBOSS:
5675 67 doortype=dt_obos;
5676 67 break;
5677
5678 case dBOMBED:
5679 1138 doortype=dt_bomb;
5680 1138 break;
5681
5682 default:
5683 655 return;
5684 }
5685
5686
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5111 times.
✓ Branch 4 taken 5230 times.
21740 switch(side)
5687 {
5688 case up:
5689 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5690 5629 break;
5691
5692 case down:
5693 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5694 5770 break;
5695
5696 case left:
5697 5111 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5698 5111 break;
5699
5700 case right:
5701 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5702 5230 break;
5703 }
5704 47568 }
5705
5706 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5707 {
5708 /*
5709 #define dWALL 0 // 000 0
5710 #define dBOMB 6 // 011 0
5711 #define 8 // 100 0
5712 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5713 */
5714
5715
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5716 91 return;
5717
5718 int32_t doortype;
5719
5720
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5721 {
5722 case dWALL:
5723 doortype=dt_wall;
5724 break;
5725
5726 case dWALK:
5727 doortype=dt_walk;
5728 break;
5729
5730 case dOPEN:
5731 50 doortype=dt_pass;
5732 50 break;
5733
5734 case dLOCKED:
5735 doortype=dt_lock;
5736 break;
5737
5738 case dUNLOCKED:
5739 362 doortype=dt_olck;
5740 362 break;
5741
5742 case dSHUTTER:
5743
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5744 {
5745 doortype=dt_osht;
5746 get_screen_state(cur_screen).open_doors = -4;
5747 break;
5748 }
5749
5750 [[fallthrough]];
5751 case d1WAYSHUTTER:
5752 1757 doortype=dt_shut;
5753 1757 break;
5754
5755 case dOPENSHUTTER:
5756 3958 doortype=dt_osht;
5757 3958 break;
5758
5759 case dBOSS:
5760 4 doortype=dt_boss;
5761 4 break;
5762
5763 case dOPENBOSS:
5764 51 doortype=dt_obos;
5765 51 break;
5766
5767 case dBOMBED:
5768 231 doortype=dt_bomb;
5769 231 break;
5770
5771 default:
5772 return;
5773 }
5774
5775
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5776 {
5777 case up:
5778
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5779 {
5780 case dBOMBED:
5781
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5782 {
5783 69 over_door(scr,dest,39,side,0,0);
5784 69 }
5785 [[fallthrough]];
5786 default:
5787 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5788 1860 break;
5789 }
5790
5791 1860 break;
5792
5793 case down:
5794
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5795 {
5796 case dBOMBED:
5797
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5798 {
5799 39 over_door(scr,dest,135,side,0,0);
5800 39 }
5801 [[fallthrough]];
5802 default:
5803 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5804 1357 break;
5805 }
5806
5807 1357 break;
5808
5809 case left:
5810
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5811 {
5812 case dBOMBED:
5813
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5814 {
5815 51 over_door(scr,dest,66,side,0,0);
5816 51 }
5817 [[fallthrough]];
5818 default:
5819 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5820 1514 break;
5821 }
5822
5823 1514 break;
5824
5825 case right:
5826
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5827 {
5828 case dBOMBED:
5829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5830 {
5831 72 over_door(scr,dest,77,side,0,0);
5832 72 }
5833 [[fallthrough]];
5834 default:
5835 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5836 1682 break;
5837 }
5838
5839 1682 break;
5840 }
5841 6504 }
5842
5843 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5844 {
5845
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5846 {
5847 586 putcombo(dest,x, y, combo, cset);
5848 586 }
5849 586 }
5850
5851 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5852 {
5853
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5854 {
5855 219 overcombo(dest,x, y, combo, cset);
5856 219 }
5857 293 }
5858
5859 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5860 {
5861 125 int32_t d = scr->door_combo_set;
5862
5863
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5864 {
5865 case up:
5866 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5867 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5868 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5869 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5870 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5871 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5872 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5873 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5874 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5875 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5876 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5877 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5878 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5879 43 DoorComboSets[d].bombdoorcombo_u[0],
5880 43 DoorComboSets[d].bombdoorcset_u[0]);
5881 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5882 43 DoorComboSets[d].bombdoorcombo_u[1],
5883 43 DoorComboSets[d].bombdoorcset_u[1]);
5884 43 break;
5885
5886 case down:
5887 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5888 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5889 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5890 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5891 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5892 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5893 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5894 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5895 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5896 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5897 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5898 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5899 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5900 39 DoorComboSets[d].bombdoorcombo_d[0],
5901 39 DoorComboSets[d].bombdoorcset_d[0]);
5902 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5903 39 DoorComboSets[d].bombdoorcombo_d[1],
5904 39 DoorComboSets[d].bombdoorcset_d[1]);
5905 39 break;
5906
5907 case left:
5908 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5909 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5910 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5911 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5912 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5913 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5914 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5915 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5916 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5917 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5918 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5919 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5920 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5921 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5922 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5923 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5924 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5925 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5926 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5927 6 DoorComboSets[d].bombdoorcombo_l[0],
5928 6 DoorComboSets[d].bombdoorcset_l[0]);
5929 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5930 6 DoorComboSets[d].bombdoorcombo_l[1],
5931 6 DoorComboSets[d].bombdoorcset_l[1]);
5932 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5933 6 DoorComboSets[d].bombdoorcombo_l[2],
5934 6 DoorComboSets[d].bombdoorcset_l[2]);
5935 6 break;
5936
5937 case right:
5938 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5939 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5940 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5941 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5942 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5943 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5944 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5945 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5946 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5947 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5948 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5949 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5950 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5951 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5952 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5953 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5954 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5955 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5956 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5957 37 DoorComboSets[d].bombdoorcombo_r[0],
5958 37 DoorComboSets[d].bombdoorcset_r[0]);
5959 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5960 37 DoorComboSets[d].bombdoorcombo_r[1],
5961 37 DoorComboSets[d].bombdoorcset_r[1]);
5962 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5963 37 DoorComboSets[d].bombdoorcombo_r[2],
5964 37 DoorComboSets[d].bombdoorcset_r[2]);
5965 37 break;
5966 }
5967 125 }
5968
5969 5360233 void openshutters(mapscr* scr)
5970 {
5971 5360233 bool opened_door = false;
5972
2/2
✓ Branch 0 taken 5360233 times.
✓ Branch 1 taken 21440932 times.
26801165 for(int32_t i=0; i<4; i++)
5973
2/2
✓ Branch 0 taken 21436974 times.
✓ Branch 1 taken 3958 times.
21444890 if(scr->door[i]==dSHUTTER)
5974 {
5975 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5976 3958 scr->door[i]=dOPENSHUTTER;
5977 3958 opened_door = true;
5978 3958 }
5979
5980 5360233 auto& combo_cache = combo_caches::shutter;
5981 2073415061 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
5982
3/4
✓ Branch 0 taken 2066444153 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1610668 times.
✗ Branch 3 not taken.
2068054828 if (!combo_cache.minis[handle.data()].shutter)
5983 2068054821 return;
5984
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
5985 7 return trig.trigger_flags.get(TRIGFLAG_SHUTTER);
5986 });
5987 2068054828 });
5988
5989
2/2
✓ Branch 0 taken 5357502 times.
✓ Branch 1 taken 2731 times.
5360233 if(opened_door)
5990 2731 sfx(WAV_DOOR);
5991 5360233 }
5992
5993 15119647 void clear_darkroom_bitmaps()
5994 {
5995 15119647 clear_to_color(darkscr_bmp, game->get_darkscr_color());
5996 15119647 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
5997 15119647 }
5998
5999 16034042 bool is_dark(const mapscr* scr)
6000 {
6001 16034042 bool dark = scr->flags&fDARK;
6002
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16030320 times.
16034042 if (region_is_lit) return !dark;
6003 16030320 return dark;
6004 16034042 }
6005
6006 39226 bool scrolling_is_dark(const mapscr* scr)
6007 {
6008 39226 bool dark = scr->flags&fDARK;
6009
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 39224 times.
39226 if (scrolling_region_is_lit) return !dark;
6010 39224 return dark;
6011 39226 }
6012
6013 36759 bool is_any_dark()
6014 {
6015 36759 bool dark = false;
6016 74774 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
6017 38015 dark |= (bool)(is_dark(scr));
6018 38015 });
6019 36759 return dark;
6020 }
6021
6022
3/4
✓ Branch 0 taken 2912 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2496 times.
✓ Branch 3 taken 416 times.
2912 static mapscr prev_origin_scrs[7];
6023 416 static std::set<int> loadscr_ffc_script_ids_to_remove;
6024
6025 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
6026 {
6027 mapscr* base_scr = screens[0];
6028 mapscr* previous_scr = &prev_origin_scrs[0];
6029
6030 for (int i = 0; i < 176; i++)
6031 {
6032 if (base_scr->data[i] == 0)
6033 {
6034 base_scr->data[i] = previous_scr->data[i];
6035 base_scr->sflag[i] = previous_scr->sflag[i];
6036 base_scr->cset[i] = previous_scr->cset[i];
6037 }
6038 }
6039
6040 for (int i = 0; i < 6; i++)
6041 {
6042 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
6043 {
6044 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
6045 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
6046
6047 for (int j = 0; j < 176; j++)
6048 {
6049 if (TheMaps[lm].data[j] == 0)
6050 {
6051 TheMaps[lm].data[j] = TheMaps[fm].data[j];
6052 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
6053 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
6054 }
6055 }
6056 }
6057 }
6058
6059 for (int i = 1; i <= 6; i++)
6060 {
6061 mapscr* scr = screens[i];
6062 previous_scr = &prev_origin_scrs[i];
6063
6064 if (scr->layermap[i] > 0)
6065 {
6066 for (int y = 0; y < 11; y++)
6067 {
6068 for (int x = 0; x < 16; x++)
6069 {
6070 int c = y*16+x;
6071
6072 if (scr->data[c]==0)
6073 {
6074 scr->data[c] = previous_scr->data[c];
6075 scr->sflag[c] = previous_scr->sflag[c];
6076 scr->cset[c] = previous_scr->cset[c];
6077 }
6078 }
6079 }
6080 }
6081 }
6082 }
6083
6084 37099 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
6085 {
6086 37099 std::vector<mapscr*> screens;
6087
6088
1/2
✓ Branch 0 taken 37099 times.
✗ Branch 1 not taken.
37099 const mapscr* source = get_canonical_scr(cur_map, screen);
6089
2/4
✓ Branch 0 taken 37099 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37099 times.
✗ Branch 3 not taken.
37099 mapscr* base_scr = new mapscr(*source);
6090 37099 temporary_screens[screen*7] = base_scr;
6091
1/2
✓ Branch 0 taken 37099 times.
✗ Branch 1 not taken.
37099 screens.push_back(base_scr);
6092
6093 37099 base_scr->valid |= mVALID; // layer 0 is always valid
6094
6095
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35855 times.
37099 if (screen == cur_screen)
6096 35855 origin_scr = base_scr;
6097
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35855 times.
37099 if (screen == Hero.current_screen)
6098 35855 hero_scr = prev_hero_scr = base_scr;
6099
6100
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 36980 times.
37099 if (source->script > 0)
6101
1/2
✓ Branch 0 taken 119 times.
✗ Branch 1 not taken.
119 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6102
6103
2/2
✓ Branch 0 taken 37099 times.
✓ Branch 1 taken 222594 times.
259693 for (int i = 0; i < 6; i++)
6104 {
6105
2/2
✓ Branch 0 taken 173512 times.
✓ Branch 1 taken 49082 times.
222594 if(source->layermap[i]>0)
6106 {
6107
3/6
✓ Branch 0 taken 49082 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49082 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49082 times.
✗ Branch 5 not taken.
49082 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
6108 49082 layer_scr->map = cur_map;
6109 49082 layer_scr->screen = screen;
6110 49082 layer_scr->valid |= mVALID;
6111
1/2
✓ Branch 0 taken 49082 times.
✗ Branch 1 not taken.
49082 screens.push_back(layer_scr);
6112 49082 }
6113 else
6114 {
6115
2/4
✓ Branch 0 taken 173512 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 173512 times.
✗ Branch 3 not taken.
173512 mapscr* layer_scr = new mapscr();
6116 173512 layer_scr->map = cur_map;
6117 173512 layer_scr->screen = screen;
6118
1/2
✓ Branch 0 taken 173512 times.
✗ Branch 1 not taken.
173512 screens.push_back(layer_scr);
6119 }
6120 222594 temporary_screens[screen*7+i+1] = screens[i+1];
6121 222594 }
6122
6123
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37099 times.
37099 if (screen_overlay)
6124 handle_screen_overlay(screens);
6125
6126
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 36955 times.
37099 if (ffc_overlay)
6127 {
6128 144 mapscr* previous_scr = &prev_origin_scrs[0];
6129
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 int num_ffcs = previous_scr->numFFC();
6130
2/2
✓ Branch 0 taken 4608 times.
✓ Branch 1 taken 144 times.
4752 for (int i = 0; i < num_ffcs; i++)
6131 {
6132
2/2
✓ Branch 0 taken 4334 times.
✓ Branch 1 taken 274 times.
4608 if ((previous_scr->ffcs[i].flags&ffc_carryover))
6133 {
6134
2/4
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 274 times.
✗ Branch 3 not taken.
274 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
6135 274 ffc.screen_spawned = screen;
6136
6137
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
6138
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
6139
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 274 times.
274 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
6140 {
6141 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
6142 }
6143 274 }
6144 4608 }
6145 144 }
6146
6147
1/2
✓ Branch 0 taken 37099 times.
✗ Branch 1 not taken.
1141915 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6148
1/2
✓ Branch 0 taken 37099 times.
✗ Branch 1 not taken.
37099 int num_ffcs = base_scr->numFFC();
6149
2/2
✓ Branch 0 taken 1104816 times.
✓ Branch 1 taken 37099 times.
1141915 for (word i = 0; i < num_ffcs; i++)
6150 {
6151 1104816 base_scr->ffcs[i].screen_spawned = screen;
6152
1/2
✓ Branch 0 taken 1104816 times.
✗ Branch 1 not taken.
1104816 base_scr->ffcs[i].x += offx;
6153
1/2
✓ Branch 0 taken 1104816 times.
✗ Branch 1 not taken.
1104816 base_scr->ffcs[i].y += offy;
6154 1104816 }
6155 37099 }
6156
6157 37099 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
6158 {
6159 37099 mapscr* base_scr = get_scr(screen);
6160 37099 int mi = mapind(cur_map, screen);
6161
6162 // Apply perm secrets, if applicable.
6163
2/2
✓ Branch 0 taken 11520 times.
✓ Branch 1 taken 25579 times.
37099 if (canPermSecret(dmap, screen))
6164 {
6165
2/2
✓ Branch 0 taken 23054 times.
✓ Branch 1 taken 2525 times.
25579 if(game->maps[mi] & mSECRET) // if special stuff done before
6166 {
6167 2525 reveal_hidden_stairs(base_scr, screen, false);
6168 2525 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
6169 2525 }
6170
2/2
✓ Branch 0 taken 25576 times.
✓ Branch 1 taken 3 times.
25579 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
6171 {
6172
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
6173 {
6174 21 mapscr* layer_scr = get_scr_layer(screen, layer);
6175
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
6176 {
6177 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
6178
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
6179 {
6180
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
6181 {
6182 3 layer_scr->data[pos] += 1;
6183 3 }
6184 3 }
6185 3696 }
6186 21 }
6187 3 }
6188 25579 }
6189
6190 37099 auto screen_handles = create_screen_handles(base_scr);
6191
6192 37099 int destlvl = DMaps[dmap].level;
6193 37099 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6194 37099 toggle_gswitches_load(screen_handles);
6195
6196 37099 bool should_check_for_state_things = (screen < 0x80);
6197
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36192 times.
37099 if (should_check_for_state_things)
6198 {
6199
2/2
✓ Branch 0 taken 35820 times.
✓ Branch 1 taken 372 times.
36192 if (game->maps[mi]&mLOCKBLOCK)
6200 372 remove_lockblocks(screen_handles);
6201
2/2
✓ Branch 0 taken 36134 times.
✓ Branch 1 taken 58 times.
36192 if (game->maps[mi]&mBOSSLOCKBLOCK)
6202 58 remove_bosslockblocks(screen_handles);
6203
2/2
✓ Branch 0 taken 36036 times.
✓ Branch 1 taken 156 times.
36192 if (game->maps[mi]&mCHEST)
6204 156 remove_chests(screen_handles);
6205
1/2
✓ Branch 0 taken 36192 times.
✗ Branch 1 not taken.
36192 if (game->maps[mi]&mLOCKEDCHEST)
6206 remove_lockedchests(screen_handles);
6207
2/2
✓ Branch 0 taken 36181 times.
✓ Branch 1 taken 11 times.
36192 if (game->maps[mi]&mBOSSCHEST)
6208 11 remove_bosschests(screen_handles);
6209
6210 36192 clear_xdoors_mi(screen_handles, mi, true);
6211 36192 clear_xstatecombos_mi(screen_handles, mi, true);
6212 36192 }
6213
6214 // check doors
6215
2/2
✓ Branch 0 taken 25578 times.
✓ Branch 1 taken 11521 times.
37099 if (isdungeon(dmap, screen))
6216 {
6217
2/2
✓ Branch 0 taken 46084 times.
✓ Branch 1 taken 11521 times.
57605 for(int32_t i=0; i<4; i++)
6218 {
6219 46084 int32_t door=base_scr->door[i];
6220
6221
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36475 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46084 switch(door)
6222 {
6223 case d1WAYSHUTTER:
6224 case dSHUTTER:
6225
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == Hero.current_screen)
6226 {
6227 1694 base_scr->door[i]=dOPENSHUTTER;
6228 1694 }
6229
6230 5303 get_screen_state(screen).open_doors = -4;
6231 5303 break;
6232
6233 case dLOCKED:
6234
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6235 {
6236 1473 base_scr->door[i]=dUNLOCKED;
6237 1473 }
6238
6239 2372 break;
6240
6241 case dBOSS:
6242
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6243 {
6244 62 base_scr->door[i]=dOPENBOSS;
6245 62 }
6246
6247 230 break;
6248
6249 case dBOMB:
6250
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6251 {
6252 1087 base_scr->door[i]=dBOMBED;
6253 1087 }
6254
6255 1704 break;
6256 }
6257
6258 46084 update_door(base_scr, i, base_scr->door[i]);
6259
6260
4/4
✓ Branch 0 taken 41517 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40781 times.
46084 if(door==dSHUTTER||door==d1WAYSHUTTER)
6261 {
6262 5303 base_scr->door[i]=door;
6263 5303 }
6264 46084 }
6265 11521 }
6266
6267
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 36962 times.
37099 if (!(base_scr->flags3 & fCYCLEONINIT))
6268 36962 return;
6269
6270
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 959 times.
1096 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6271 {
6272
4/4
✓ Branch 0 taken 822 times.
✓ Branch 1 taken 137 times.
✓ Branch 2 taken 377 times.
✓ Branch 3 taken 445 times.
959 if (j<0 || base_scr->layermap[j] > 0)
6273 {
6274 514 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6275
3/4
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 377 times.
514 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6276 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6277
6278
2/2
✓ Branch 0 taken 90464 times.
✓ Branch 1 taken 514 times.
90978 for(int32_t i=0; i<176; ++i)
6279 {
6280 90464 int32_t c=layerscreen->data[i];
6281
6282 // New screen flag: Cycle Combos At Screen Init
6283
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 90399 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
90464 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6284 {
6285 65 int32_t r = 0;
6286
6287
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6288 {
6289 84 newcombo const& cmb = combobuf[c];
6290 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6292 84 layerscreen->data[i] = cid;
6293
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6294
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6295 84 c = layerscreen->data[i];
6296 }
6297 65 }
6298 90464 }
6299 514 }
6300 959 }
6301 37099 }
6302
6303 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6304 //
6305 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6306 // the game, etc...)
6307 //
6308 // Note: for regions, only the initial screen load calls this function. Simply walking between
6309 // screens in the same region does not use this, because every screen in a region is loaded into
6310 // temporary memory up front.
6311 //
6312 // If scr >= 0x80, `Hero.current_screen` will be saved to `home_screen` and also be loaded into
6313 // `special_warp_return_scr`.
6314 //
6315 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6316 // on all layers (but only where the new screen has a 0 combo).
6317 //
6318 // TODO: loadscr should set curdmap, but currently callers do that.
6319 35855 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6320 {
6321 35855 zapp_reporting_set_tag("screen", screen);
6322
2/2
✓ Branch 0 taken 8929 times.
✓ Branch 1 taken 26926 times.
35855 if (destdmap != -1)
6323 8929 zapp_reporting_set_tag("dmap", destdmap);
6324
6325 35855 int32_t orig_destdmap = destdmap;
6326
2/2
✓ Branch 0 taken 8929 times.
✓ Branch 1 taken 26926 times.
35855 if (destdmap < 0) destdmap = cur_dmap;
6327
6328
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35855 times.
35855 if (replay_is_active())
6329 {
6330
1/2
✓ Branch 0 taken 35855 times.
✗ Branch 1 not taken.
35855 if (replay_get_mode() == ReplayMode::ManualTakeover)
6331 replay_stop_manual_takeover();
6332
6333
2/2
✓ Branch 0 taken 26926 times.
✓ Branch 1 taken 8929 times.
35855 if (orig_destdmap != -1)
6334 {
6335
2/2
✓ Branch 0 taken 7858 times.
✓ Branch 1 taken 1071 times.
8929 if (strlen(DMaps[orig_destdmap].name) > 0)
6336 {
6337
1/2
✓ Branch 0 taken 7858 times.
✗ Branch 1 not taken.
7858 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6338 7858 }
6339 else
6340 {
6341
1/2
✓ Branch 0 taken 1071 times.
✗ Branch 1 not taken.
1071 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6342 }
6343 8929 }
6344 35855 replay_step_comment_loadscr(screen);
6345
6346 // Reset the rngs and frame count so that recording steps can be modified without impacting
6347 // behavior of later screens.
6348 35855 replay_sync_rng();
6349 35855 }
6350
6351
2/2
✓ Branch 0 taken 1707536 times.
✓ Branch 1 taken 35855 times.
1743391 for (auto& state : get_screen_states())
6352 1707536 state.second.triggered_secrets = false;
6353 35855 slopes.clear();
6354 35855 Hero.clear_platform_ffc();
6355 35855 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6356 35855 clear_darkroom_bitmaps();
6357 35855 msgscr = nullptr;
6358
6359
2/2
✓ Branch 0 taken 50392033 times.
✓ Branch 1 taken 35855 times.
50427888 for (word x=0; x<animated_combos; x++)
6360 {
6361
2/2
✓ Branch 0 taken 20920015 times.
✓ Branch 1 taken 29472018 times.
50392033 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6362 {
6363 20920015 combobuf[animated_combo_table4[x][0]].aclk = 0;
6364 20920015 }
6365 50392033 }
6366 35855 reset_combo_animations2();
6367 35855 region_is_lit = false;
6368
6369 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6370 // of the new ones.
6371 35855 bool origin_ffc_overlay = false;
6372
2/2
✓ Branch 0 taken 1138 times.
✓ Branch 1 taken 34717 times.
35855 if (origin_scr)
6373 {
6374
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 34715 times.
34717 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6375 {
6376 34715 int c = origin_scr->numFFC();
6377
2/2
✓ Branch 0 taken 34571 times.
✓ Branch 1 taken 1038879 times.
1073450 for (int i = 0; i < c; i++)
6378 {
6379
2/2
✓ Branch 0 taken 1038735 times.
✓ Branch 1 taken 144 times.
1038879 if (origin_scr->ffcs[i].flags&ffc_carryover)
6380 {
6381 144 origin_ffc_overlay = true;
6382 144 break;
6383 }
6384 1038735 }
6385 34715 }
6386
6387
3/4
✓ Branch 0 taken 34717 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
✓ Branch 3 taken 34573 times.
34717 if (origin_screen_overlay || origin_ffc_overlay)
6388 {
6389
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 144 times.
1152 for (int i = 0; i <= 6; i++)
6390 {
6391 1008 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6392
1/2
✓ Branch 0 taken 1008 times.
✗ Branch 1 not taken.
1008 if (prev_scr)
6393 1008 prev_origin_scrs[i] = *prev_scr;
6394 else
6395 prev_origin_scrs[i] = {};
6396 1008 }
6397 144 }
6398 34717 }
6399
6400 // When loading a new screen, all previous FFC scripts end, with one exception.
6401 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6402 // them, but scripts that need their data to persist will be removed.
6403 35855 loadscr_ffc_script_ids_to_remove.clear();
6404
2/2
✓ Branch 0 taken 74699211 times.
✓ Branch 1 taken 35855 times.
74735066 for (auto& key : scriptEngineDatas | std::views::keys)
6405 {
6406
2/2
✓ Branch 0 taken 73577306 times.
✓ Branch 1 taken 1121905 times.
74699211 if (key.first == ScriptType::FFC)
6407 1121905 loadscr_ffc_script_ids_to_remove.insert(key.second);
6408 }
6409
6410 35855 load_region(destdmap, screen);
6411
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 34948 times.
35855 home_screen = screen >= 0x80 ? Hero.current_screen : cur_screen;
6412 35855 Hero.current_screen = screen;
6413
6414 35855 cpos_clear_all();
6415 35855 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6416 35855 FFCore.clear_combo_scripts();
6417
6418
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35691 times.
35855 if (is_in_scrolling_region())
6419 {
6420
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6421 {
6422
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6423 {
6424
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6425
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6426 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6427 1408 }
6428 20992 }
6429 164 }
6430 else
6431 {
6432 35691 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6433 }
6434
6435 35855 prepare_current_region_handles();
6436
6437
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35691 times.
35855 if (is_in_scrolling_region())
6438 {
6439
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6440 {
6441
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6442 {
6443 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6444 1408 }
6445 20992 }
6446 164 }
6447 else
6448 {
6449 35691 load_a_screen_and_layers_post(destdmap, screen, ldir);
6450 }
6451
6452 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6453
2/2
✓ Branch 0 taken 34948 times.
✓ Branch 1 taken 907 times.
35855 if (screen >= 0x80)
6454
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6455
6456 35855 update_slope_comboposes();
6457 35855 cpos_force_update();
6458 35855 trig_trigger_groups();
6459
6460
2/2
✓ Branch 0 taken 1121631 times.
✓ Branch 1 taken 35855 times.
1157486 for (int index : loadscr_ffc_script_ids_to_remove)
6461 {
6462 // Note: ideally would use "destroySprite", but during scrolling the previous
6463 // screen's FFCs are still accessible (even though only the new screen's FFC scripts run).
6464 // The only difference is a call to "release_sprite_owned_objects". To defer FFC script
6465 // owned objects being released until the end of the scroll, here "destroyScriptableObject"
6466 // is used instead.
6467 //
6468 // So when is "release_sprite_owned_objects" called for FFCs? For scrolling screen
6469 // transitions, it's at the end of "scrollscr" via "delete_temporary_screens". Otherwise,
6470 // it is called above when "load_region" calls "clear_temporary_screens".
6471 1121631 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6472 }
6473
6474 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6475 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6476 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6477 // It is up to the quest designer to make their subscreen be actually transparent.
6478 //
6479 // When not in "extended height mode" (otherwise 56 is 0):
6480 // - playing_field_offset: 56, but changes during earthquakes
6481 // - original_playing_field_offset: always 56
6482 //
6483 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6484 // - yofs of sprites
6485 // - bitmap y offsets in draw_screen
6486 // - drawing offsets for putscr, do_layer
6487 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6488 // - lots more
6489 //
6490 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6491
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 35713 times.
35855 if (is_extended_height_mode())
6492 {
6493 142 playing_field_offset = 0;
6494 142 original_playing_field_offset = 0;
6495 // A few sprites exist as globals, so we must manually reset them.
6496 142 Hero.yofs = 0;
6497 142 mblock2.yofs = 0;
6498 142 }
6499 else
6500 {
6501 35713 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6502 35713 original_playing_field_offset = 56;
6503 }
6504 35855 is_any_room_dark = is_any_dark();
6505
6506 35855 game->load_portal();
6507 35855 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6508
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 35820 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
35855 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6509 {
6510 delete Hero.lift_wpn;
6511 Hero.lift_wpn = nullptr;
6512 }
6513
6514 35855 enemy_spawning_has_checked_been_here = false;
6515 35855 markBmap(-1, Hero.current_screen);
6516 35855 Hero.maybe_begin_advanced_maze();
6517 35855 }
6518
6519 // Don't use this directly! Use `loadscr` instead.
6520 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6521 {
6522
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6523
6524 907 mapscr previous_scr = *special_warp_return_scr;
6525 907 mapscr* scr = special_warp_return_scr;
6526
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6527
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6528
6529
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6530 {
6531
2/2
✓ Branch 0 taken 5059 times.
✓ Branch 1 taken 383 times.
5442 if (scr->layermap[i-1] > 0)
6532
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6533 else
6534
2/4
✓ Branch 0 taken 5059 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5059 times.
✗ Branch 3 not taken.
5059 special_warp_return_scrs[i] = {};
6535 5442 }
6536
6537 907 scr->valid |= mVALID; //layer 0 is always valid
6538
6539
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6540 {
6541 scr->script = source->script;
6542 for ( int32_t q = 0; q < 8; q++ )
6543 {
6544 scr->screeninitd[q] = source->screeninitd[q];
6545 }
6546 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6547 }
6548 else
6549 {
6550 907 scr->script = 0;
6551 }
6552
6553
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6554 {
6555 for(int32_t c=0; c< 176; ++c)
6556 {
6557 if(scr->data[c]==0)
6558 {
6559 scr->data[c]=previous_scr.data[c];
6560 scr->sflag[c]=previous_scr.sflag[c];
6561 scr->cset[c]=previous_scr.cset[c];
6562 }
6563 }
6564
6565 for(int32_t i=0; i<6; i++)
6566 {
6567 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6568 {
6569 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6570 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6571
6572 for(int32_t c=0; c< 176; ++c)
6573 {
6574 if(TheMaps[lm].data[c]==0)
6575 {
6576 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6577 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6578 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6579 }
6580 }
6581 }
6582 }
6583 }
6584
6585
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6586
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6587
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6588 {
6589 28993 scr->ffcs[i].screen_spawned = screen;
6590
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6591
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6592 28993 }
6593
6594 907 int mi = mapind(cur_map, screen);
6595
6596 // Apply perm secrets, if applicable.
6597
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6598 {
6599
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6600 {
6601
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6602
6603
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6604
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6605 204 bool do_replay_comment = true;
6606 204 bool from_active_screen = false;
6607
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6608 204 }
6609
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6610 {
6611 for (int layer = 0; layer <= 6; layer++)
6612 {
6613 mapscr* tscr = &special_warp_return_scrs[layer];
6614 for (int pos = 0; pos < 176; pos++)
6615 {
6616 newcombo const* cmb = &combobuf[tscr->data[pos]];
6617 if(cmb->type == cLIGHTTARGET)
6618 {
6619 if(!(cmb->usrflags&cflag1)) //Unlit version
6620 {
6621 tscr->data[pos] += 1;
6622 }
6623 }
6624 }
6625 }
6626 }
6627 536 }
6628
6629 screen_handles_t screen_handles;
6630
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6631
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1284 times.
✓ Branch 3 taken 5065 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6632
6633
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6634
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6635
6636
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6637 {
6638
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6639 5 }
6640
6641
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6642 {
6643
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6644 1 }
6645
6646
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6647 {
6648 remove_chests(screen_handles);
6649 }
6650
6651
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6652 {
6653 remove_lockedchests(screen_handles);
6654 }
6655
6656
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6657 {
6658 remove_bosschests(screen_handles);
6659 }
6660
6661
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6662
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6663
6664 // check doors
6665
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if (isdungeon(destdmap, screen))
6666 {
6667
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6668 {
6669 1484 int32_t door=scr->door[i];
6670
6671
4/5
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1295 times.
1484 switch(door)
6672 {
6673 case d1WAYSHUTTER:
6674 case dSHUTTER:
6675 if ((ldir^1)==i && screen == home_screen)
6676 {
6677 scr->door[i]=dOPENSHUTTER;
6678 }
6679
6680 get_screen_state(screen).open_doors = -4;
6681 105 break;
6682
6683 case dLOCKED:
6684
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 80 times.
91 if(game->maps[mi]&(mDOOR_UP<<i))
6685 {
6686 80 scr->door[i]=dUNLOCKED;
6687 80 }
6688
6689 91 break;
6690
6691 case dBOSS:
6692
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
9 if(game->maps[mi]&(mDOOR_UP<<i))
6693 {
6694 5 scr->door[i]=dOPENBOSS;
6695 5 }
6696
6697 9 break;
6698
6699 case dBOMB:
6700
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 51 times.
89 if(game->maps[mi]&(mDOOR_UP<<i))
6701 {
6702 51 scr->door[i]=dBOMBED;
6703 51 }
6704
6705 89 break;
6706 }
6707
6708
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 105 times.
1589 update_door(scr, i, scr->door[i]);
6709
6710
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6711 {
6712 105 scr->door[i]=door;
6713 105 }
6714 1484 }
6715 371 }
6716
6717
2/2
✓ Branch 0 taken 6139 times.
✓ Branch 1 taken 1117 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6718 {
6719
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 697 times.
✓ Branch 2 taken 593 times.
✓ Branch 3 taken 4849 times.
6139 if (j<0 || scr->layermap[j] > 0)
6720 {
6721
4/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 907 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
1290 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6722 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6723
6724
2/2
✓ Branch 0 taken 226830 times.
✓ Branch 1 taken 1500 times.
228330 for(int32_t i=0; i<176; ++i)
6725 {
6726 226830 int32_t c=layerscreen->data[i];
6727
6728 // New screen flag: Cycle Combos At Screen Init
6729
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 226824 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 210 times.
✓ Branch 7 taken 210 times.
226830 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6730 {
6731 210 int32_t r = 0;
6732
6733
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
210 while(combobuf[c].can_cycle() && r++ < 10)
6734 {
6735 newcombo const& cmb = combobuf[c];
6736 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6737 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6738 layerscreen->data[i] = cid;
6739 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6740 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6741 c = layerscreen->data[i];
6742 }
6743 }
6744 227040 }
6745 1500 }
6746 6349 }
6747 1537 }
6748
6749 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6750 // instead returns an array of mapscr.
6751 // Used to draw/save the map.
6752 45680 std::array<mapscr, 7> loadscr2(int32_t screen)
6753 {
6754 45680 std::array<mapscr, 7> scrs;
6755 45680 mapscr* scr = &scrs[0];
6756
6757
2/2
✓ Branch 0 taken 64716181 times.
✓ Branch 1 taken 45680 times.
64761861 for(word x=0; x<animated_combos; x++)
6758 {
6759
2/2
✓ Branch 0 taken 31963685 times.
✓ Branch 1 taken 32752496 times.
64716181 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6760 {
6761 32752496 combobuf[animated_combo_table4[x][0]].aclk=0;
6762 32752496 }
6763 64716181 }
6764
6765
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 const mapscr* source = get_canonical_scr(cur_map, screen);
6766
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!source->is_valid())
6767 {
6768 scrs[0].valid = 0;
6769 return scrs;
6770 }
6771
6772
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 *scr = *get_canonical_scr(cur_map, screen);
6773
2/2
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
319760 for (int i = 1; i <= 6; i++)
6774 {
6775
2/2
✓ Branch 0 taken 209266 times.
✓ Branch 1 taken 64814 times.
274080 if (scr->layermap[i-1] > 0)
6776
2/4
✓ Branch 0 taken 64814 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64814 times.
✗ Branch 3 not taken.
64814 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6777 else
6778
2/4
✓ Branch 0 taken 209266 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 209266 times.
✗ Branch 3 not taken.
209266 scrs[i] = {};
6779 274080 }
6780
6781 screen_handles_t screen_handles;
6782
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i < 7; i++)
6783
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103061 times.
✓ Branch 3 taken 216699 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6784
6785 45680 int mi = mapind(cur_map, screen);
6786
6787
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45626 times.
✓ Branch 3 taken 54 times.
45680 if(canPermSecret(-1,screen))
6788 {
6789
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5730 times.
✓ Branch 3 taken 39896 times.
45626 if(game->maps[mi]&mSECRET) // if special stuff done before
6790 {
6791
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 reveal_hidden_stairs(scr, screen, false);
6792 5730 bool from_active_screen = false;
6793 5730 bool do_replay_comment = true;
6794
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6795 5730 }
6796
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45609 times.
✓ Branch 3 taken 17 times.
45626 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6797 {
6798
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6799 {
6800 119 mapscr* tscr = &scrs[layer];
6801
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6802 {
6803 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6804
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6805 {
6806
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6807 {
6808 17 tscr->data[pos] += 1;
6809 17 }
6810 17 }
6811 20944 }
6812 119 }
6813 17 }
6814 45626 }
6815
6816
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 233 times.
✓ Branch 3 taken 45447 times.
45680 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6817 {
6818
1/2
✓ Branch 0 taken 233 times.
✗ Branch 1 not taken.
233 remove_lockblocks(screen_handles);
6819 233 }
6820
6821
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 45679 times.
45680 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6822 {
6823
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6824 1 }
6825
6826
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 45579 times.
45680 if(game->maps[mi]&mCHEST) // if special stuff done before
6827 {
6828
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 remove_chests(screen_handles);
6829 101 }
6830
6831
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 45656 times.
45680 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6832 {
6833
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6834 24 }
6835
6836
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6837 {
6838 remove_bosschests(screen_handles);
6839 }
6840
6841
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xdoors(screen_handles);
6842
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xstatecombos(screen_handles);
6843
6844 // check doors
6845
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45626 times.
✓ Branch 3 taken 54 times.
45680 if (isdungeon(screen))
6846 {
6847
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6848 {
6849 216 int32_t door=scr->door[i];
6850 216 bool putit=true;
6851
6852
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6853 {
6854 case d1WAYSHUTTER:
6855 case dSHUTTER:
6856 61 break;
6857
6858 case dLOCKED:
6859
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(mDOOR_UP<<i))
6860 {
6861 12 scr->door[i]=dUNLOCKED;
6862 12 }
6863
6864 12 break;
6865
6866 case dBOSS:
6867
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(mDOOR_UP<<i))
6868 {
6869 scr->door[i]=dOPENBOSS;
6870 }
6871
6872 4 break;
6873
6874 case dBOMB:
6875 if(game->maps[mi]&(mDOOR_UP<<i))
6876 {
6877 scr->door[i]=dBOMBED;
6878 }
6879
6880 break;
6881 }
6882
6883
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6884 {
6885
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6886 216 }
6887
6888
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6889 {
6890 61 scr->door[i]=door;
6891 61 }
6892 216 }
6893 54 }
6894
6895
2/2
✓ Branch 0 taken 319760 times.
✓ Branch 1 taken 45680 times.
365440 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6896 {
6897
4/4
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
✓ Branch 2 taken 64814 times.
✓ Branch 3 taken 209266 times.
319760 if (j < 0 || scr->layermap[j] > 0)
6898 {
6899
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 45680 times.
110494 mapscr *layerscreen= (j<0 ? scr
6900 64814 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6901
6902
2/2
✓ Branch 0 taken 19446944 times.
✓ Branch 1 taken 110494 times.
19557438 for(int32_t i=0; i<176; ++i)
6903 {
6904 19446944 int32_t c=layerscreen->data[i];
6905
6906 // New screen flag: Cycle Combos At Screen Init
6907
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19446944 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19446944 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6908 {
6909 int32_t r = 0;
6910
6911 while(combobuf[c].can_cycle() && r++ < 10)
6912 {
6913 newcombo const& cmb = combobuf[c];
6914 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6915 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6916 layerscreen->data[i] = cid;
6917 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6918 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6919 c = layerscreen->data[i];
6920 }
6921 }
6922 19446944 }
6923 110494 }
6924 319760 }
6925
6926 45680 return scrs;
6927
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 }
6928
6929 19018981 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6930 {
6931 // This is a bogus value while screenscrolling == true, but that's ok
6932 // because it is only used to calculate the rpos, and during screenscrolling
6933 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6934 // is always the same no matter the value of scr.
6935 19018981 int screen = get_screen_for_world_xy(x, y);
6936
6937 19018981 x -= viewport.x;
6938 19018981 y -= viewport.y;
6939
6940
3/6
✓ Branch 0 taken 19018981 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19018981 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19018981 times.
19018981 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6941 {
6942 rectfill(dest,x,y,x+255,y+175,0);
6943 return;
6944 }
6945
6946 37909053 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6947
2/2
✓ Branch 0 taken 18890072 times.
✓ Branch 1 taken 128909 times.
19018981 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
6948
2/2
✓ Branch 0 taken 66419 times.
✓ Branch 1 taken 18823653 times.
18890072 || !get_qr(qr_CLASSIC_DRAWING_ORDER);
6949
6950 int start_x, end_x, start_y, end_y;
6951 19018981 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6952
2/2
✓ Branch 0 taken 19018981 times.
✓ Branch 1 taken 202581278 times.
221600259 for (int cy = start_y; cy < end_y; cy++)
6953 {
6954
2/2
✓ Branch 0 taken 3076350642 times.
✓ Branch 1 taken 202581278 times.
3278931920 for (int cx = start_x; cx < end_x; cx++)
6955 {
6956 3076350642 int i = cx + cy*16;
6957
2/2
✓ Branch 0 taken 357850966 times.
✓ Branch 1 taken 2718499676 times.
3076350642 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6958 3076350642 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6959 3076350642 }
6960 202581278 }
6961 19018981 }
6962
6963 15542695 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6964 {
6965
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15542695 times.
15542695 if (!show_layers[0])
6966 {
6967 return;
6968 }
6969
6970 15542695 x -= viewport.x;
6971 15542695 y -= viewport.y;
6972
6973
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15542695 times.
31221708 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6974 15679013 mapscr* scr = screen_handles[0].base_scr;
6975
1/2
✓ Branch 0 taken 15679013 times.
✗ Branch 1 not taken.
15679013 if (!scr->is_valid())
6976 return;
6977
6978
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 15555602 times.
15679013 if(scr->door[0]==dBOMBED)
6979 {
6980 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
6981 123411 }
6982
6983
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 15535904 times.
15679013 if(scr->door[1]==dBOMBED)
6984 {
6985 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
6986 143109 }
6987
6988
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 15523151 times.
15679013 if(scr->door[2]==dBOMBED)
6989 {
6990 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
6991 155862 }
6992
6993
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 15546724 times.
15679013 if(scr->door[3]==dBOMBED)
6994 {
6995 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
6996 132289 }
6997 15679013 });
6998 15542695 }
6999
7000 3339968 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
7001 {
7002
2/4
✓ Branch 0 taken 3339968 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3339968 times.
✗ Branch 3 not taken.
3339968 if (!scr->is_valid() || !show_layers[0])
7003 return;
7004
7005 3339968 x -= viewport.x;
7006 3339968 y -= viewport.y;
7007
7008
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3302312 times.
3339968 if(scr->door[0]==dBOMBED)
7009 {
7010 37656 over_door(scr,dest,39,up,x,y);
7011 37656 }
7012
7013
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3303473 times.
3339968 if(scr->door[1]==dBOMBED)
7014 {
7015 36495 over_door(scr,dest,135,down,x,y);
7016 36495 }
7017
7018
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3299528 times.
3339968 if(scr->door[2]==dBOMBED)
7019 {
7020 40440 over_door(scr,dest,66,left,x,y);
7021 40440 }
7022
7023
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3302905 times.
3339968 if(scr->door[3]==dBOMBED)
7024 {
7025 37063 over_door(scr,dest,77,right,x,y);
7026 37063 }
7027 3339968 }
7028 233976507 static inline bool standing_on_z(newcombo const& cmb, zfix const& standing_z_state)
7029 {
7030
1/2
✓ Branch 0 taken 233976507 times.
✗ Branch 1 not taken.
233976507 if (cmb.dive_under_level)
7031 {
7032 if (standing_z_state <= -cmb.dive_under_level)
7033 return true;
7034 }
7035
7036 233976507 zfix cmb_z, cmb_z_step;
7037
4/4
✓ Branch 0 taken 92789 times.
✓ Branch 1 taken 233883718 times.
✓ Branch 2 taken 88819 times.
✓ Branch 3 taken 3970 times.
233976507 if(cmb.type == cCSWITCHBLOCK && (cmb.usrflags & cflag9))
7038 {
7039 3970 cmb_z = zslongToFix(cmb.attributes[2]);
7040
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3970 times.
3970 cmb_z_step = zslongToFix(zc_max(0,cmb.attributes[3]));
7041 3970 }
7042
2/2
✓ Branch 0 taken 1983 times.
✓ Branch 1 taken 233970554 times.
233972537 else if(cmb.genflags & cflag3)
7043 {
7044 1983 cmb_z = cmb.z_height;
7045
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 cmb_z_step = zc_max(0_zf,cmb.z_step_height);
7046 1983 }
7047 233970554 else return false;
7048
7049
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
5953 if (standing_z_state == STANDING_Z_MAX) // 'infinity'
7050 return true;
7051
2/2
✓ Branch 0 taken 1149 times.
✓ Branch 1 taken 4804 times.
5953 if (!cmb_z) return false; // infinite height
7052
7053 4804 return (cmb_z - cmb_z_step) <= standing_z_state;
7054 233976507 }
7055 56124214 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
7056 {
7057 56124214 return _walkflag(zx,zy,cnt,0_zf);
7058 }
7059
7060 132933147 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& standing_z_state, bool is_temp_screens)
7061 {
7062 132933147 int x = zx.getRound(), y = zy.getRound();
7063 132933147 int pos = COMBOPOS(x % 256, y % 176);
7064 132933147 const newcombo& c = combobuf[s0->data[pos]];
7065 132933147 const newcombo& c1 = combobuf[s1->data[pos]];
7066 132933147 const newcombo& c2 = combobuf[s2->data[pos]];
7067
4/4
✓ Branch 0 taken 130937706 times.
✓ Branch 1 taken 1995441 times.
✓ Branch 2 taken 130928246 times.
✓ Branch 3 taken 9460 times.
266068582 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7068
4/4
✓ Branch 0 taken 101153 times.
✓ Branch 1 taken 131029381 times.
✓ Branch 2 taken 2101809 times.
✓ Branch 3 taken 4245 times.
132933147 (iswater_type(c2.type))) && DRIEDLAKE);
7069 133135435 int32_t b=1;
7070
2/2
✓ Branch 0 taken 65635176 times.
✓ Branch 1 taken 67500259 times.
133135435 if(x&8) b<<=2;
7071
2/2
✓ Branch 0 taken 62193091 times.
✓ Branch 1 taken 70942344 times.
133135435 if(y&8) b<<=1;
7072
7073 133135435 int32_t cwalkflag = c.walk;
7074
4/4
✓ Branch 0 taken 133034291 times.
✓ Branch 1 taken 101144 times.
✓ Branch 2 taken 133034127 times.
✓ Branch 3 taken 164 times.
133135435 if(is_temp_screens && standing_on_z(c,standing_z_state)) cwalkflag &= (c.walk>>4)^0xF;
7075
8/10
✓ Branch 0 taken 50572 times.
✓ Branch 1 taken 133084699 times.
✓ Branch 2 taken 2096585 times.
✓ Branch 3 taken 2046013 times.
✓ Branch 4 taken 2096585 times.
✓ Branch 5 taken 133034127 times.
✓ Branch 6 taken 2096585 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2096585 times.
✗ Branch 9 not taken.
133135271 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7076
2/2
✓ Branch 0 taken 63211281 times.
✓ Branch 1 taken 69823010 times.
133034291 if (s1 != s0)
7077 {
7078
3/4
✓ Branch 0 taken 69823010 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69822392 times.
✓ Branch 3 taken 618 times.
69823010 if(is_temp_screens && standing_on_z(c1,standing_z_state)) cwalkflag &= (c1.walk>>4)^0xF;
7079
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69810663 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
69822392 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
7080
2/2
✓ Branch 0 taken 62906 times.
✓ Branch 1 taken 69759486 times.
69822392 else if (c1.type == cBRIDGE)
7081 {
7082
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62906 times.
62906 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7083 {
7084 62906 int efflag = (c1.walk & 0xF0)>>4;
7085 62906 int newsolid = (c1.walk & 0xF);
7086 62906 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7087 62906 }
7088 else cwalkflag &= c1.walk;
7089 62906 }
7090
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69747757 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
69759486 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
7091 69759486 else cwalkflag |= c1.walk;
7092 69823010 }
7093
2/2
✓ Branch 0 taken 101915085 times.
✓ Branch 1 taken 31119206 times.
133034291 if (s2 != s0)
7094 {
7095
2/4
✓ Branch 0 taken 31119206 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 31119206 times.
✗ Branch 3 not taken.
31119206 if(is_temp_screens && standing_on_z(c2,standing_z_state)) cwalkflag &= (c2.walk>>4)^0xF;
7096
4/10
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 31117052 times.
✓ Branch 2 taken 2154 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2154 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
31119206 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
7097
2/2
✓ Branch 0 taken 4447 times.
✓ Branch 1 taken 31114759 times.
31119206 else if (c2.type == cBRIDGE)
7098 {
7099
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
4447 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7100 {
7101 4447 int efflag = (c2.walk & 0xF0)>>4;
7102 4447 int newsolid = (c2.walk & 0xF);
7103 4447 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7104 4447 }
7105 else cwalkflag &= c2.walk;
7106 4447 }
7107
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 31112605 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
31114759 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
7108 31114759 else cwalkflag |= c2.walk;
7109 31119206 }
7110
7111
4/4
✓ Branch 0 taken 29568194 times.
✓ Branch 1 taken 103466097 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 29567246 times.
133034291 if((cwalkflag&b) && !dried)
7112 29567246 return true;
7113
7114
3/4
✓ Branch 0 taken 103467045 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103450634 times.
✓ Branch 3 taken 16411 times.
103467045 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
7115
7116 103450634 return false;
7117 133034291 }
7118
7119 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
7120 133034291 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& standing_z_state)
7121 {
7122 133034291 int x = zx.getRound(), y = zy.getRound();
7123 133034291 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
7124 133034291 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7125 133034291 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7126
2/2
✓ Branch 0 taken 63211281 times.
✓ Branch 1 taken 69823010 times.
133034291 if (!s1->valid) s1 = s0;
7127
2/2
✓ Branch 0 taken 101915085 times.
✓ Branch 1 taken 31119206 times.
133034291 if (!s2->valid) s2 = s0;
7128 133034291 return _walkflag_new(s0, s1, s2, zx, zy, standing_z_state, true);
7129 }
7130
7131 128600476 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& standing_z_state)
7132 {
7133 128600476 int max_x = world_w;
7134 128600476 int max_y = world_h;
7135
2/2
✓ Branch 0 taken 68557739 times.
✓ Branch 1 taken 60042737 times.
128600476 if (!get_qr(qr_LTTPWALK))
7136 {
7137 60042737 max_x -= 7;
7138 60042737 max_y -= 7;
7139 60042737 }
7140
4/4
✓ Branch 0 taken 128329644 times.
✓ Branch 1 taken 270832 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 128246376 times.
128600476 if (x < 0 || y < 0) return false;
7141
2/2
✓ Branch 0 taken 322356 times.
✓ Branch 1 taken 127924020 times.
128246376 if (x >= max_x) return false;
7142
3/4
✓ Branch 0 taken 539693 times.
✓ Branch 1 taken 127384327 times.
✓ Branch 2 taken 539693 times.
✗ Branch 3 not taken.
127924020 if (x >= max_x - 8 && cnt == 2) return false;
7143
2/2
✓ Branch 0 taken 127374796 times.
✓ Branch 1 taken 549224 times.
127924020 if (y >= max_y) return false;
7144
7145
4/4
✓ Branch 0 taken 29465504 times.
✓ Branch 1 taken 97909292 times.
✓ Branch 2 taken 92249797 times.
✓ Branch 3 taken 5659495 times.
127374796 return _walkflag_new(x, y, standing_z_state) || (cnt != 1 && _walkflag_new(x + 8, y, standing_z_state));
7146 128600476 }
7147
7148 99165582 static bool effectflag(int32_t x, int32_t y, int32_t layer)
7149 {
7150 99165582 mapscr* s0 = get_scr_for_world_xy(x, y);
7151 99165582 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7152 99165582 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7153
2/2
✓ Branch 0 taken 51697279 times.
✓ Branch 1 taken 47468303 times.
99165582 if (!s1->valid) s1 = s0;
7154
2/2
✓ Branch 0 taken 18770050 times.
✓ Branch 1 taken 80395532 times.
99165582 if (!s2->valid) s2 = s0;
7155
7156 99165582 int pos = COMBOPOS(x % 256, y % 176);
7157 99165582 const newcombo& c = combobuf[s0->data[pos]];
7158 99165582 const newcombo& c1 = combobuf[s1->data[pos]];
7159 99165582 const newcombo& c2 = combobuf[s2->data[pos]];
7160
4/4
✓ Branch 0 taken 98240543 times.
✓ Branch 1 taken 925039 times.
✓ Branch 2 taken 98239263 times.
✓ Branch 3 taken 1280 times.
198331164 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7161
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 98239263 times.
✓ Branch 2 taken 924635 times.
✓ Branch 3 taken 1684 times.
99165582 (iswater_type(c2.type))) && DRIEDLAKE);
7162 99165582 int32_t b=1;
7163
2/2
✓ Branch 0 taken 50180986 times.
✓ Branch 1 taken 48984596 times.
99165582 if(x&8) b<<=2;
7164
2/2
✓ Branch 0 taken 41928447 times.
✓ Branch 1 taken 57237135 times.
99165582 if(y&8) b<<=1;
7165
7166 99165582 int32_t cwalkflag = (c.walk>>4);
7167
2/2
✓ Branch 0 taken 76365197 times.
✓ Branch 1 taken 22800385 times.
99165582 if (layer == 0) cwalkflag = (c1.walk>>4);
7168
2/2
✓ Branch 0 taken 76366395 times.
✓ Branch 1 taken 22799187 times.
99165582 if (layer == 1) cwalkflag = (c2.walk>>4);
7169 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7170
4/4
✓ Branch 0 taken 51697279 times.
✓ Branch 1 taken 47468303 times.
✓ Branch 2 taken 22531992 times.
✓ Branch 3 taken 29165287 times.
99165582 if (s1 != s0 && layer < 0)
7171 {
7172
2/2
✓ Branch 0 taken 22518486 times.
✓ Branch 1 taken 13506 times.
22531992 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
7173 22531992 }
7174
4/4
✓ Branch 0 taken 18770050 times.
✓ Branch 1 taken 80395532 times.
✓ Branch 2 taken 13845049 times.
✓ Branch 3 taken 4925001 times.
99165582 if (s2 != s0 && layer < 1)
7175 {
7176
2/2
✓ Branch 0 taken 13839189 times.
✓ Branch 1 taken 5860 times.
13845049 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
7177 13845049 }
7178
7179
2/2
✓ Branch 0 taken 99006258 times.
✓ Branch 1 taken 159324 times.
99165582 return (cwalkflag&b) ? !dried : false;
7180 }
7181
7182 99538906 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
7183 {
7184 DCHECK(cnt == 0 || cnt == 1);
7185 99538906 int max_x = world_w;
7186 99538906 int max_y = world_h;
7187
3/4
✓ Branch 0 taken 45833723 times.
✓ Branch 1 taken 53705183 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45833723 times.
99538906 if (!get_qr(qr_LTTPWALK) && !notLink)
7188 {
7189 45833723 max_x -= 7;
7190 45833723 max_y -= 7;
7191 45833723 }
7192
4/4
✓ Branch 0 taken 99538154 times.
✓ Branch 1 taken 752 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 99537950 times.
99538906 if (x < 0 || y < 0) return false;
7193
2/2
✓ Branch 0 taken 816 times.
✓ Branch 1 taken 99537134 times.
99537950 if (x >= max_x) return false;
7194
3/4
✓ Branch 0 taken 520208 times.
✓ Branch 1 taken 99016926 times.
✓ Branch 2 taken 520208 times.
✗ Branch 3 not taken.
99537134 if (x >= max_x - 8 && cnt == 2) return false;
7195
2/2
✓ Branch 0 taken 371552 times.
✓ Branch 1 taken 99165582 times.
99537134 if (y >= max_y) return false;
7196
7197
3/4
✓ Branch 0 taken 99005468 times.
✓ Branch 1 taken 160114 times.
✓ Branch 2 taken 160114 times.
✗ Branch 3 not taken.
99165582 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
7198 99538906 }
7199
7200 // used by mapdata->isSolid(x,y) in ZScript
7201 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7202 {
7203 int x = zx.getRound(), y = zy.getRound();
7204 {
7205 int max_x = 256;
7206 int max_y = 176;
7207 if (!get_qr(qr_LTTPWALK))
7208 {
7209 max_x -= 7;
7210 max_y -= 7;
7211 }
7212 if (x < 0 || y < 0) return false;
7213 if (x >= max_x) return false;
7214 if (x >= max_x - 8 && cnt == 2) return false;
7215 if (y >= max_y) return false;
7216 }
7217
7218 const mapscr *s1, *s2;
7219
7220 if ( m->layermap[0] > 0 )
7221 {
7222 s1 = get_canonical_scr(m->layermap[0], m->layerscreen[0]);
7223 }
7224 else s1 = m;
7225
7226 if ( m->layermap[1] > 0 )
7227 {
7228 s2 = get_canonical_scr(m->layermap[1], m->layerscreen[1]);
7229 }
7230 else s2 = m;
7231
7232 zfix unused;
7233 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
7234 }
7235
7236 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
7237 {
7238 DCHECK_LAYER_NEG1_INDEX(layer);
7239 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7240 if (!m->is_valid()) return false;
7241 return _walkflag_layer(x, y, cnt, m);
7242 }
7243
7244 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
7245 {
7246 int x = zx.getRound(), y = zy.getRound();
7247
7248 if (!get_qr(qr_LTTPWALK))
7249 {
7250 max_x -= 7;
7251 max_y -= 7;
7252 }
7253 if (x < 0 || y < 0) return false;
7254 if (x >= max_x) return false;
7255 if (x >= max_x - 8 && cnt == 2) return false;
7256 if (y >= max_y) return false;
7257
7258 if(!m) return true;
7259
7260 int pos = COMBOPOS(x%256, y%176);
7261 const newcombo* c = &combobuf[m->data[pos]];
7262 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7263 int32_t b=1;
7264
7265 if(x&8) b<<=2;
7266
7267 if(y&8) b<<=1;
7268
7269 if((c->walk&b) && !dried)
7270 return true;
7271
7272 if(cnt==1) return false;
7273
7274 ++pos;
7275
7276 if(!(x&8))
7277 b<<=2;
7278 else
7279 {
7280 c = &combobuf[m->data[pos]];
7281 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7282 b=1;
7283
7284 if(y&8) b<<=1;
7285 }
7286
7287 return (c->walk&b) ? !dried : false;
7288 }
7289
7290 //Only check the given mapscr*, not its layer 1&2
7291 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7292 {
7293 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7294 }
7295
7296 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7297 {
7298 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7299 }
7300
7301 313631 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7302 {
7303 DCHECK_LAYER_NEG1_INDEX(layer);
7304 313631 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7305
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 311869 times.
313631 if (!m->is_valid()) return false;
7306 311869 return _effectflag_layer(x, y, cnt, m, notLink);
7307 313631 }
7308
7309 377902 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7310 {
7311 377902 int max_x = world_w;
7312 377902 int max_y = world_h;
7313
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 327900 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
377902 if (!get_qr(qr_LTTPWALK) && !notLink)
7314 {
7315 max_x -= 7;
7316 max_y -= 7;
7317 }
7318
2/4
✓ Branch 0 taken 377902 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 377902 times.
377902 if (x < 0 || y < 0) return false;
7319
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377902 times.
377902 if (x >= max_x) return false;
7320
3/4
✓ Branch 0 taken 1209 times.
✓ Branch 1 taken 376693 times.
✓ Branch 2 taken 1209 times.
✗ Branch 3 not taken.
377902 if (x >= max_x - 8 && cnt == 2) return false;
7321
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377902 times.
377902 if (y >= max_y) return false;
7322
7323
1/2
✓ Branch 0 taken 377902 times.
✗ Branch 1 not taken.
377902 if (!m) return true;
7324
7325 377902 int pos = COMBOPOS(x%256, y%176);
7326 377902 const newcombo* c = &combobuf[m->data[pos]];
7327
3/4
✓ Branch 0 taken 377502 times.
✓ Branch 1 taken 400 times.
✓ Branch 2 taken 400 times.
✗ Branch 3 not taken.
378302 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7328 377902 int32_t b=1;
7329
7330
2/2
✓ Branch 0 taken 205458 times.
✓ Branch 1 taken 172444 times.
377902 if(x&8) b<<=2;
7331
7332
2/2
✓ Branch 0 taken 157257 times.
✓ Branch 1 taken 220645 times.
377902 if(y&8) b<<=1;
7333
7334
3/4
✓ Branch 0 taken 308913 times.
✓ Branch 1 taken 68989 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 308913 times.
377902 if(((c->walk>>4)&b) && !dried)
7335 308913 return true;
7336
7337
1/2
✓ Branch 0 taken 68989 times.
✗ Branch 1 not taken.
68989 if(cnt==1) return false;
7338
7339 ++pos;
7340
7341 if(!(x&8))
7342 b<<=2;
7343 else
7344 {
7345 c = &combobuf[m->data[pos]];
7346 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7347 b=1;
7348
7349 if(y&8) b<<=1;
7350 }
7351
7352 return ((c->walk>>4)&b) ? !dried : false;
7353 377902 }
7354
7355 812605 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7356 {
7357 812605 int max_x = world_w;
7358 812605 int max_y = world_h;
7359
2/2
✓ Branch 0 taken 117367 times.
✓ Branch 1 taken 695238 times.
812605 if (!get_qr(qr_LTTPWALK))
7360 {
7361 695238 max_x -= 7;
7362 695238 max_y -= 7;
7363 695238 }
7364
2/4
✓ Branch 0 taken 812605 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 812605 times.
812605 if (x < 0 || y < 0) return false;
7365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (x >= max_x) return false;
7366
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
812605 if (x >= max_x - 8 && cnt == 2) return false;
7367
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (y >= max_y) return false;
7368
7369
3/4
✓ Branch 0 taken 16825 times.
✓ Branch 1 taken 795780 times.
✓ Branch 2 taken 795780 times.
✗ Branch 3 not taken.
812605 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7370 812605 }
7371
7372 812605 bool water_walkflag(int32_t x, int32_t y)
7373 {
7374 812605 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7375 812605 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7376 812605 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7377
7378 812605 int32_t b=1;
7379
2/2
✓ Branch 0 taken 414677 times.
✓ Branch 1 taken 397928 times.
812605 if(x&8) b<<=2;
7380
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if(y&8) b<<=1;
7381
7382
2/2
✓ Branch 0 taken 26377 times.
✓ Branch 1 taken 786228 times.
812605 if(get_qr(qr_NO_SOLID_SWIM))
7383 {
7384
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 26245 times.
26377 if(c.walk&b)
7385 132 return true;
7386
7387
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 25953 times.
26245 if(c1.walk&b)
7388 292 return true;
7389
7390
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25953 times.
25953 if(c2.walk&b)
7391 return true;
7392 25953 }
7393 else
7394 {
7395
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7396 16371 return true;
7397
7398
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7399 17 return true;
7400
7401
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7402 13 return true;
7403 }
7404
7405 795780 return false;
7406 812605 }
7407
7408 565044 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7409 {
7410
2/2
✓ Branch 0 taken 91927 times.
✓ Branch 1 taken 473117 times.
565044 if(dlevel)
7411
8/8
✓ Branch 0 taken 471712 times.
✓ Branch 1 taken 1405 times.
✓ Branch 2 taken 468517 times.
✓ Branch 3 taken 3195 times.
✓ Branch 4 taken 466857 times.
✓ Branch 5 taken 1660 times.
✓ Branch 6 taken 4199 times.
✓ Branch 7 taken 462658 times.
473117 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7412 10459 return true;
7413
7414
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 554583 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
554585 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7415 return true;
7416
7417
8/8
✓ Branch 0 taken 554316 times.
✓ Branch 1 taken 269 times.
✓ Branch 2 taken 554083 times.
✓ Branch 3 taken 233 times.
✓ Branch 4 taken 553874 times.
✓ Branch 5 taken 209 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 553528 times.
554585 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7418 1057 return true;
7419
7420 // for(int32_t i=0; i<4; i++)
7421
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 552687 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
553528 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7422 36 return true;
7423
7424
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 553492 times.
553492 if (collide_object(x, y,cnt*8, 1))
7425 return true;
7426
7427 553492 return _walkflag(x,y,cnt);
7428 565044 }
7429
7430 12110 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7431 {
7432 // 16 pixel buffer to account for slopes that are on bordering screens.
7433
4/8
✓ Branch 0 taken 12110 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12110 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12110 times.
12110 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7434 return true;
7435
7436 // for(int32_t i=0; i<4; i++)
7437
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12110 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7438 return true;
7439
7440
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
12110 if (collide_object(x, y,cnt*8, 1, ign))
7441 return true;
7442
7443 12110 return _walkflag(x,y,cnt);
7444 12110 }
7445
7446 37838 void map_bkgsfx(bool on)
7447 {
7448
2/2
✓ Branch 0 taken 37817 times.
✓ Branch 1 taken 21 times.
37838 if(on)
7449 {
7450 37817 cont_sfx(hero_scr->oceansfx);
7451
7452
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 37448 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
37817 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&(1 << li_boss_killed)))
7453 315 cont_sfx(hero_scr->bosssfx);
7454 37817 }
7455 else
7456 {
7457 21 adjust_sfx(hero_scr->oceansfx,128,false);
7458 21 adjust_sfx(hero_scr->bosssfx,128,false);
7459
7460
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7461 {
7462
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7463 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7464 114 }
7465 }
7466 37838 }
7467
7468 239 void toggle_switches(dword flags, bool entry)
7469 {
7470
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 239 times.
239 if(!flags) return; //No flags to toggle
7471
7472 478 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7473 239 toggle_switches(flags, entry, create_screen_handles(scr));
7474 239 });
7475 239 }
7476 53507 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7477 {
7478
2/2
✓ Branch 0 taken 737 times.
✓ Branch 1 taken 52770 times.
53507 if(!flags) return; //No flags to toggle
7479
7480 737 mapscr* m = screen_handles[0].base_scr;
7481 737 int screen = m->screen;
7482 737 bool is_active_screen = is_in_current_region(m);
7483
7484 357489 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7485 356752 byte togglegrid[176] = {0};
7486 356752 mapscr* scr = rpos_handle.scr;
7487 356752 int lyr = rpos_handle.layer;
7488 356752 int pos = rpos_handle.pos;
7489 356752 newcombo const& cmb = combobuf[scr->data[pos]];
7490
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 317328 times.
356752 if(is_active_screen)
7491
1/2
✓ Branch 0 taken 317328 times.
✗ Branch 1 not taken.
472669 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7492
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 155341 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
155341 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7493 }, ctrigSWITCHSTATE);
7494
3/4
✓ Branch 0 taken 356089 times.
✓ Branch 1 taken 663 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2760 times.
356752 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7495
2/2
✓ Branch 0 taken 2760 times.
✓ Branch 1 taken 353992 times.
356752 && !(cmb.usrflags & cflag11)) //global state
7496 {
7497
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2314 times.
2760 if(flags&(1<<cmb.attribytes[0]))
7498 {
7499 2314 set<int32_t> oldData;
7500 //Increment the combo/cset by the attributes
7501 2314 int32_t cmbofs = (cmb.attributes[0]/10000L);
7502 2314 int32_t csofs = (cmb.attributes[1]/10000L);
7503
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 oldData.insert(scr->data[pos]);
7504
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7505 2314 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7506
4/4
✓ Branch 0 taken 1435 times.
✓ Branch 1 taken 879 times.
✓ Branch 2 taken 1197 times.
✓ Branch 3 taken 238 times.
2314 if(entry && (cmb.usrflags&cflag8))
7507 {
7508 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7509
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7510 {
7511 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7512 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7513 if(oldData.find(cid) != oldData.end())
7514 break;
7515
7516 scr->data[pos] = cid;
7517 if(!(tmp->animflags & AF_CYCLENOCSET))
7518 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7519 oldData.insert(cid);
7520 tmp = &combobuf[cid];
7521 }
7522 238 }
7523 2314 int32_t cmbid = scr->data[pos];
7524
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2273 times.
2314 if(combobuf[cmbid].animflags & AF_CYCLE)
7525 {
7526 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7527 41 combobuf[cmbid].cur_frame=0;
7528 41 combobuf[cmbid].aclk = 0;
7529
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7530 41 }
7531 2314 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7532
2/2
✓ Branch 0 taken 511 times.
✓ Branch 1 taken 1803 times.
2314 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7533
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2147 times.
2147 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7534 {
7535
2/2
✓ Branch 0 taken 1671 times.
✓ Branch 1 taken 476 times.
2147 if(lyr==lyr2) return;
7536
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 344 times.
476 if(!(cmb.usrflags&(1<<lyr2))) return;
7537
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(togglegrid[pos]&(1<<lyr2)) return;
7538
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
344 mapscr* scr_2 = (lyr2 ? get_scr_layer(screen, lyr2) : m);
7539
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7540 return;
7541 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7542
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7543 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7544 return; //This is a switch/block that will be hit later in the loop!
7545 344 set<int32_t> oldData2;
7546 //Increment the combo/cset by the original cmb's attributes
7547
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7548
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7549 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7550
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7551 {
7552 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7553 while(tmp->can_cycle())
7554 {
7555 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7556 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7557 if(oldData2.find(cid) != oldData2.end())
7558 break;
7559
7560 scr_2->data[pos] = cid;
7561 if(!(tmp->animflags & AF_CYCLENOCSET))
7562 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7563 oldData2.insert(cid);
7564 tmp = &combobuf[cid];
7565 }
7566 }
7567 344 int32_t cmbid2 = scr_2->data[pos];
7568
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7569 {
7570 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7571 combobuf[cmbid2].cur_frame=0;
7572 combobuf[cmbid2].aclk = 0;
7573 combo_caches::drawing.refresh(cmbid2);
7574 }
7575 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7576 344 }
7577
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2314 times.
✗ Branch 2 not taken.
2314 }
7578 446 }
7579 356752 });
7580
7581
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 218 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
737 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7582 {
7583 newcombo const& cmb = combobuf[mblock2.bcombo];
7584 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7585 {
7586 if(flags&(1<<cmb.attribytes[0]))
7587 {
7588 //Increment the combo/cset by the attributes
7589 int32_t cmbofs = (cmb.attributes[0]/10000L);
7590 int32_t csofs = (cmb.attributes[1]/10000L);
7591 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7592 mblock2.cs = (mblock2.cs + csofs) & 15;
7593 int32_t cmbid = mblock2.bcombo;
7594 if(combobuf[cmbid].animflags & AF_CYCLE)
7595 {
7596 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7597 combobuf[cmbid].cur_frame=0;
7598 combobuf[cmbid].aclk = 0;
7599 combo_caches::drawing.refresh(cmbid);
7600 }
7601 }
7602 }
7603 }
7604
7605
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 513 times.
737 if (is_active_screen)
7606 {
7607 513 int screen_index_offset = get_region_screen_offset(m->screen);
7608 513 word c = m->numFFC();
7609
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 513 times.
847 for (int q = 0; q < c; ++q)
7610 {
7611 334 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7612
1/2
✓ Branch 0 taken 334 times.
✗ Branch 1 not taken.
363 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7613
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
29 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7614 }, ctrigSWITCHSTATE);
7615 334 }
7616 513 }
7617 53507 }
7618
7619 1 void toggle_gswitches(int32_t state, bool entry)
7620 {
7621 2 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7622 1 toggle_gswitches(state, entry, create_screen_handles(scr));
7623 1 });
7624 1 }
7625 1 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7626 {
7627 1 bool states[256] = {false};
7628 1 states[state] = true;
7629 1 toggle_gswitches(states, entry, screen_handles);
7630 1 }
7631 15218661 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7632 {
7633
1/2
✓ Branch 0 taken 15218661 times.
✗ Branch 1 not taken.
15218661 if(!states) return;
7634
7635 15218661 auto& combo_cache = combo_caches::gswitch;
7636 15218661 mapscr* base_scr = screen_handles[0].base_scr;
7637 15218661 int screen = base_scr->screen;
7638 15218661 bool is_active_screen = is_in_current_region(base_scr);
7639 15218661 byte togglegrid[176] = {0};
7640
2/2
✓ Branch 0 taken 15218661 times.
✓ Branch 1 taken 106530627 times.
121749288 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7641 {
7642 106530627 mapscr* scr = screen_handles[lyr].scr;
7643
2/2
✓ Branch 0 taken 33026952 times.
✓ Branch 1 taken 73503675 times.
106530627 if (!scr)
7644 73503675 continue;
7645
7646
2/2
✓ Branch 0 taken 33026952 times.
✓ Branch 1 taken 5812743552 times.
5845770504 for(int32_t pos = 0; pos < 176; ++pos)
7647 {
7648 5812743552 int cid = scr->data[pos];
7649 5812743552 auto& mini_cmb = combo_cache.minis[cid];
7650
7651
2/2
✓ Branch 0 taken 2910336 times.
✓ Branch 1 taken 5809833216 times.
5812743552 if (is_active_screen)
7652 {
7653
2/2
✓ Branch 0 taken 5809831334 times.
✓ Branch 1 taken 1882 times.
5809833216 if (mini_cmb.trigger_global_state)
7654 {
7655 1882 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7656
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
3764 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7657
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1882 times.
1882 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7658 }, ctrigSWITCHSTATE);
7659 1882 }
7660 5809833216 }
7661
7662
2/2
✓ Branch 0 taken 40395 times.
✓ Branch 1 taken 5812703157 times.
5812743552 if (!mini_cmb.has_global_state)
7663 5812703157 continue;
7664
7665 40395 newcombo const& cmb = combobuf[cid];
7666
2/4
✓ Branch 0 taken 40395 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40395 times.
40395 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7667 {
7668 if(states[cmb.attribytes[0]])
7669 {
7670 set<int32_t> oldData;
7671 //Increment the combo/cset by the attributes
7672 int32_t cmbofs = (cmb.attributes[0]/10000L);
7673 int32_t csofs = (cmb.attributes[1]/10000L);
7674 oldData.insert(scr->data[pos]);
7675 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7676 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7677 if(entry && (cmb.usrflags&cflag8))
7678 {
7679 newcombo const* tmp = &combobuf[scr->data[pos]];
7680 while(tmp->can_cycle())
7681 {
7682 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7683 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7684 if(oldData.find(cid) != oldData.end())
7685 break;
7686 scr->data[pos] = cid;
7687 if(!(tmp->animflags & AF_CYCLENOCSET))
7688 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7689 oldData.insert(cid);
7690 tmp = &combobuf[cid];
7691 }
7692 }
7693 int32_t cmbid = scr->data[pos];
7694 if(combobuf[cmbid].animflags & AF_CYCLE)
7695 {
7696 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7697 combobuf[cmbid].cur_frame=0;
7698 combobuf[cmbid].aclk = 0;
7699 combo_caches::drawing.refresh(cmbid);
7700 }
7701 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7702 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7703 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7704 {
7705 if(lyr==lyr2) continue;
7706 if(!(cmb.usrflags&(1<<lyr2))) continue;
7707 if(togglegrid[pos]&(1<<lyr2)) continue;
7708 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7709 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7710 continue;
7711 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7712 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7713 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7714 continue; //This is a switch/block that will be hit later in the loop!
7715 set<int32_t> oldData2;
7716 //Increment the combo/cset by the original cmb's attributes
7717 oldData2.insert(scr_2->data[pos]);
7718 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7719 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7720 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7721 {
7722 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7723 while(tmp->can_cycle())
7724 {
7725 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7726 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7727 if(oldData2.find(cid) != oldData2.end())
7728 break;
7729 scr_2->data[pos] = cid;
7730 if(!(tmp->animflags & AF_CYCLENOCSET))
7731 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7732 oldData2.insert(cid);
7733 tmp = &combobuf[cid];
7734 }
7735 }
7736 int32_t cmbid2 = scr_2->data[pos];
7737 if(combobuf[cmbid2].animflags & AF_CYCLE)
7738 {
7739 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7740 combobuf[cmbid2].cur_frame=0;
7741 combobuf[cmbid2].aclk = 0;
7742 combo_caches::drawing.refresh(cmbid2);
7743 }
7744 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7745 }
7746 }
7747 }
7748 40395 }
7749 33026952 }
7750
7751
4/4
✓ Branch 0 taken 549907 times.
✓ Branch 1 taken 14668754 times.
✓ Branch 2 taken 545163 times.
✓ Branch 3 taken 4744 times.
15218661 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7752 {
7753 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7754
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7755 {
7756 if(states[cmb.attribytes[0]])
7757 {
7758 //Increment the combo/cset by the attributes
7759 int32_t cmbofs = (cmb.attributes[0]/10000L);
7760 int32_t csofs = (cmb.attributes[1]/10000L);
7761 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7762 mblock2.cs = (mblock2.cs + csofs) & 15;
7763 int32_t cmbid = mblock2.bcombo;
7764 if(combobuf[cmbid].animflags & AF_CYCLE)
7765 {
7766 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7767 combobuf[cmbid].cur_frame=0;
7768 combobuf[cmbid].aclk = 0;
7769 combo_caches::drawing.refresh(cmbid);
7770 }
7771 }
7772 }
7773 4744 }
7774
7775
2/2
✓ Branch 0 taken 16159 times.
✓ Branch 1 taken 15202502 times.
15218661 if(is_active_screen)
7776 {
7777 15202502 int screen_index_offset = get_region_screen_offset(screen);
7778 15202502 word c = base_scr->numFFC();
7779
2/2
✓ Branch 0 taken 454486335 times.
✓ Branch 1 taken 15202502 times.
469688837 for (int q = 0; q < c; ++q)
7780 {
7781 454486335 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7782
1/2
✓ Branch 0 taken 454486335 times.
✗ Branch 1 not taken.
454715123 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7783
1/2
✓ Branch 0 taken 228788 times.
✗ Branch 1 not taken.
228788 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7784 }, ctrigSWITCHSTATE);
7785 454486335 }
7786 15202502 }
7787 15218661 }
7788 53268 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7789 {
7790 bool states[256];
7791
2/2
✓ Branch 0 taken 13636608 times.
✓ Branch 1 taken 53268 times.
13689876 for(auto q = 0; q < 256; ++q)
7792 {
7793 13636608 states[q] = game->gswitch_timers[q] != 0;
7794 13636608 }
7795 53268 toggle_gswitches(states, true, screen_handles);
7796 53268 }
7797 14776024 void run_gswitch_timers()
7798 {
7799 14776024 bool states[256] = {false};
7800 14776024 auto& m = game->gswitch_timers.mut_inner();
7801
2/2
✓ Branch 0 taken 3778619904 times.
✓ Branch 1 taken 14776024 times.
3793395928 for(auto it = m.begin(); it != m.end();)
7802 {
7803
2/2
✓ Branch 0 taken 3778619304 times.
✓ Branch 1 taken 600 times.
3778619904 if(it->second > 0)
7804
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 1 times.
600 if(!--it->second)
7805 {
7806 1 states[it->first] = true;
7807 1 it = m.erase(it);
7808 1 continue;
7809 }
7810 3778619903 ++it;
7811 }
7812 29941416 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7813 15165392 toggle_gswitches(states, false, create_screen_handles(scr));
7814 15165392 });
7815 14776024 }
7816 1117 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7817 {
7818
2/2
✓ Branch 0 taken 285952 times.
✓ Branch 1 taken 1117 times.
287069 for(auto q = 0; q < 256; ++q)
7819 {
7820
1/2
✓ Branch 0 taken 285952 times.
✗ Branch 1 not taken.
285952 if(game->gswitch_timers[q] > 0)
7821 game->gswitch_timers[q] = 0;
7822 285952 }
7823 1117 }
7824
7825 /**** View Map ****/
7826
7827 int32_t mapres = 0;
7828 int32_t view_map_show_mode = 3;
7829
7830 124544 bool displayOnMap(int32_t x, int32_t y)
7831 {
7832 124544 int32_t s = (y<<4) + x;
7833 124544 int mi = mapind(cur_map, s);
7834
2/2
✓ Branch 0 taken 67891 times.
✓ Branch 1 taken 56653 times.
124544 if (!(game->maps[mi]&mVISITED))
7835 67891 return false;
7836
7837 // Don't display if not part of DMap
7838
4/4
✓ Branch 0 taken 15628 times.
✓ Branch 1 taken 41025 times.
✓ Branch 2 taken 4655 times.
✓ Branch 3 taken 4311 times.
65619 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7839
1/2
✓ Branch 0 taken 15628 times.
✗ Branch 1 not taken.
15628 (DMaps[cur_dmap].type != dmOVERW) &&
7840
2/2
✓ Branch 0 taken 12495 times.
✓ Branch 1 taken 3133 times.
15628 !(x >= DMaps[cur_dmap].xoff &&
7841
2/2
✓ Branch 0 taken 8966 times.
✓ Branch 1 taken 3529 times.
12495 x < DMaps[cur_dmap].xoff+8 &&
7842 8966 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7843 10973 return false;
7844 else
7845 45680 return true;
7846 124544 }
7847
7848 973 void ViewMap()
7849 {
7850 973 ViewingMap = true;
7851
7852 973 BITMAP* mappic = NULL;
7853 static double scales[17] =
7854 {
7855 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7856 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7857 };
7858
7859 // Cursor position for hero, in absolute map coordinates.
7860 973 int32_t lx = ((cur_screen & 15) << 8) + HeroX() + 8;
7861 973 int32_t ly = ((cur_screen >> 4) * 176) + HeroY() + 8;
7862
7863 int32_t px;
7864 int32_t py;
7865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 973 times.
973 if (is_in_scrolling_region())
7866 {
7867 // Center the player on the middle of the map view.
7868 px = (16*256/2 - lx) * 2;
7869 py = (8*176/2 - ly) * 2;
7870 }
7871 else
7872 {
7873 // Center the current screen on the middle of the map view.
7874 973 px = ((8-(cur_screen&15)) << 9) - 256;
7875 973 py = ((4-(cur_screen>>4)) * 352) - 176;
7876 }
7877
7878 973 int32_t sc = 6;
7879
7880 973 bool done=false, redraw=true;
7881
7882 973 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7883
7884
1/2
✓ Branch 0 taken 973 times.
✗ Branch 1 not taken.
973 if(!mappic)
7885 {
7886 enter_sys_pal();
7887 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7888 exit_sys_pal();
7889 return;
7890 }
7891
7892 973 clear_to_color(mappic, WHITE);
7893
7894 973 auto prev_viewport = viewport;
7895 973 viewport.x = 0;
7896 973 viewport.y = 0;
7897
7898 // draw the map
7899 973 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7900 973 combotile_add_x = 256;
7901 973 combotile_add_y = 0;
7902 973 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
7903
2/2
✓ Branch 0 taken 7784 times.
✓ Branch 1 taken 973 times.
8757 for(int32_t y=0; y<8; y++)
7904 {
7905
2/2
✓ Branch 0 taken 7784 times.
✓ Branch 1 taken 124544 times.
132328 for(int32_t x=0; x<16; x++)
7906 {
7907
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 78864 times.
124544 if (!displayOnMap(x, y))
7908 78864 continue;
7909
7910 45680 int screen = map_scr_xy_to_index(x, y);
7911 45680 auto scrs = loadscr2(screen);
7912 45680 mapscr* scr = &scrs[0];
7913
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!scr->is_valid())
7914 continue;
7915
7916 screen_handles_t screen_handles;
7917
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i <= 6; i++)
7918
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103061 times.
✓ Branch 3 taken 216699 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7919
7920 45680 int xx = 0;
7921 45680 int yy = -playing_field_offset;
7922
7923
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 if (!classic_draw)
7924 for (int layer = -7; layer <= -4; ++layer)
7925 do_ffc_layer(screen_bmp, layer, screen_handles[0], xx, yy);
7926
7927
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 if(classic_draw)
7928 {
7929
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 45660 times.
45680 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7930
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7931
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7932 45680 }
7933
7934
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 45505 times.
45680 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7935
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7936
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7937
7938
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45680 times.
45680 if(!classic_draw)
7939 {
7940 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7941 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7942 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7943 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7944 }
7945
7946
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7947
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7948
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7949
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7950
7951
2/2
✓ Branch 0 taken 45660 times.
✓ Branch 1 taken 20 times.
45680 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7952 {
7953
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7954
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7955 45660 }
7956
7957
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 putscrdoors(scr, screen_bmp, xx, yy);
7958
2/2
✓ Branch 0 taken 41678 times.
✓ Branch 1 taken 4002 times.
45680 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7959 {
7960
1/2
✓ Branch 0 taken 41678 times.
✗ Branch 1 not taken.
41678 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7961
2/2
✓ Branch 0 taken 1782 times.
✓ Branch 1 taken 39896 times.
41678 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7962 {
7963
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7964
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7965 1782 }
7966 41678 }
7967
7968
2/2
✓ Branch 0 taken 45505 times.
✓ Branch 1 taken 175 times.
45680 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7969 {
7970
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7971
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7972 45505 }
7973
7974
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7975
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7976
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7977
2/2
✓ Branch 0 taken 5784 times.
✓ Branch 1 taken 39896 times.
45680 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
7978 {
7979
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
7980
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
7981 5784 }
7982
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
7983
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
7984
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(replay_version_check(40))
7985 do_ffc_layer(screen_bmp, -1000, screen_handles[0], xx, yy);
7986
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
7987
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
7988
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
7989
7990
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
7991
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
45680 }
7992 7784 }
7993
7994 973 viewport = prev_viewport;
7995 973 combotile_add_x = 0;
7996 973 combotile_add_y = 0;
7997
7998 973 destroy_bitmap(screen_bmp);
7999 973 clear_keybuf();
8000 973 pause_all_sfx();
8001
8002 // view it
8003 973 int32_t delay = 0;
8004
8005 973 do
8006 {
8007
2/2
✓ Branch 0 taken 178717 times.
✓ Branch 1 taken 29891 times.
208608 if (replay_version_check(0, 11))
8008 29891 load_control_state();
8009
8010 208608 int32_t step = int32_t(16.0/scales[sc]);
8011 208608 step = (step>>1) + (step&1);
8012 208608 bool r = cRbtn();
8013
8014
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(cLbtn())
8015 {
8016 step <<= 2;
8017 delay = 0;
8018 }
8019
8020
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 208608 times.
208608 if(r)
8021 {
8022 if(rUp())
8023 {
8024 py+=step;
8025 redraw=true;
8026 }
8027
8028 if(rDown())
8029 {
8030 py-=step;
8031 redraw=true;
8032 }
8033
8034 if(rLeft())
8035 {
8036 px+=step;
8037 redraw=true;
8038 }
8039
8040 if(rRight())
8041 {
8042 px-=step;
8043 redraw=true;
8044 }
8045 }
8046 else
8047 {
8048
2/2
✓ Branch 0 taken 193729 times.
✓ Branch 1 taken 14879 times.
208608 if(Up())
8049 {
8050 14879 py+=step;
8051 14879 redraw=true;
8052 14879 }
8053
8054
2/2
✓ Branch 0 taken 193574 times.
✓ Branch 1 taken 15034 times.
208608 if(Down())
8055 {
8056 15034 py-=step;
8057 15034 redraw=true;
8058 15034 }
8059
8060
2/2
✓ Branch 0 taken 182159 times.
✓ Branch 1 taken 26449 times.
208608 if(Left())
8061 {
8062 26449 px+=step;
8063 26449 redraw=true;
8064 26449 }
8065
8066
2/2
✓ Branch 0 taken 182774 times.
✓ Branch 1 taken 25834 times.
208608 if(Right())
8067 {
8068 25834 px-=step;
8069 25834 redraw=true;
8070 25834 }
8071 }
8072
8073
2/2
✓ Branch 0 taken 21164 times.
✓ Branch 1 taken 187444 times.
208608 if(delay)
8074 21164 --delay;
8075 else
8076 {
8077 187444 bool a = cAbtn();
8078 187444 bool b = cBbtn();
8079
8080
3/4
✓ Branch 0 taken 1721 times.
✓ Branch 1 taken 185723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1721 times.
187444 if(a && !b)
8081 {
8082
1/2
✓ Branch 0 taken 1721 times.
✗ Branch 1 not taken.
1721 sc=zc_min(sc+1,16);
8083 1721 delay=8;
8084 1721 redraw=true;
8085 1721 }
8086
8087
3/4
✓ Branch 0 taken 927 times.
✓ Branch 1 taken 186517 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 927 times.
187444 if(b && !a)
8088 {
8089
2/2
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 1 times.
927 sc=zc_max(sc-1,0);
8090 927 delay=8;
8091 927 redraw=true;
8092 927 }
8093 }
8094
8095
2/2
✓ Branch 0 taken 208597 times.
✓ Branch 1 taken 11 times.
208608 if(rPbtn())
8096 11 --view_map_show_mode;
8097
8098 208608 px = vbound(px,-4096,4096);
8099 208608 py = vbound(py,-1408,1408);
8100
8101 208608 double scale = scales[sc];
8102
8103
2/2
✓ Branch 0 taken 72838 times.
✓ Branch 1 taken 135770 times.
208608 if(!redraw)
8104 {
8105 135770 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
8106 135770 }
8107 else
8108 {
8109 72838 clear_to_color(framebuf,BLACK);
8110 145676 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
8111 72838 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
8112 72838 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
8113
8114 72838 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
8115 72838 redraw=false;
8116 }
8117
8118 208608 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
8119 208608 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
8120
8121
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 201142 times.
208608 if(view_map_show_mode&1)
8122 {
8123 201142 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
8124 201142 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
8125 201142 }
8126
8127
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 203008 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
208608 if(view_map_show_mode&2 || r)
8128 203008 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
8129
8130
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(r)
8131 {
8132 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
8133 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
8134 }
8135
8136 208608 advanceframe(false, false);
8137
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 178717 times.
208608 if (replay_version_check(11))
8138 178717 load_control_state();
8139
8140
2/2
✓ Branch 0 taken 207636 times.
✓ Branch 1 taken 972 times.
208608 if (getInput(btnS, INPUT_PRESS | INPUT_IGNORE_DISABLE))
8141 972 done = true;
8142
8143
2/2
✓ Branch 0 taken 207635 times.
✓ Branch 1 taken 973 times.
417216 }
8144
2/2
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 207636 times.
208608 while(!done && !Quit);
8145
8146 973 ViewingMap = false;
8147 973 destroy_bitmap(mappic);
8148 973 resume_all_sfx();
8149 973 }
8150
8151 1075 int32_t onViewMap()
8152 {
8153
4/6
✓ Branch 0 taken 1075 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1075 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 973 times.
1075 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
8154 {
8155 973 clear_to_color(framebuf,BLACK);
8156 973 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
8157 973 advanceframe(true);
8158 973 ViewMap();
8159 973 }
8160
8161 1075 return D_O_K;
8162 }
8163
8164 35784859 bool isGrassType(int32_t type)
8165 {
8166
2/2
✓ Branch 0 taken 35108447 times.
✓ Branch 1 taken 676412 times.
35784859 switch(type)
8167 {
8168 case cTALLGRASS:
8169 case cTALLGRASSNEXT:
8170 case cTALLGRASSTOUCHY:
8171 676412 return true;
8172 }
8173
8174 35108447 return false;
8175 35784859 }
8176
8177 20914 bool isFlowersType(int32_t type)
8178 {
8179
2/2
✓ Branch 0 taken 16574 times.
✓ Branch 1 taken 4340 times.
20914 switch(type)
8180 {
8181 case cFLOWERS:
8182 case cFLOWERSTOUCHY:
8183 4340 return true;
8184 }
8185
8186 16574 return false;
8187 20914 }
8188
8189 bool isGenericType(int32_t type)
8190 {
8191 switch(type)
8192 {
8193 case cTRIGGERGENERIC:
8194 return true;
8195 }
8196
8197 return false;
8198 }
8199
8200 26056 bool isBushType(int32_t type)
8201 {
8202
2/2
✓ Branch 0 taken 20914 times.
✓ Branch 1 taken 5142 times.
26056 switch(type)
8203 {
8204 case cBUSH:
8205 case cBUSHNEXT:
8206 case cBUSHTOUCHY:
8207 case cBUSHNEXTTOUCHY:
8208
8209 5142 return true;
8210 }
8211
8212 20914 return false;
8213 26056 }
8214
8215 bool isSlashType(int32_t type)
8216 {
8217 switch(type)
8218 {
8219 case cSLASH:
8220 case cSLASHITEM:
8221 case cSLASHTOUCHY:
8222 case cSLASHITEMTOUCHY:
8223 case cSLASHNEXT:
8224 case cSLASHNEXTITEM:
8225 case cSLASHNEXTTOUCHY:
8226 case cSLASHNEXTITEMTOUCHY:
8227 return true;
8228 }
8229
8230 return false;
8231 }
8232
8233 15695 bool isCuttableNextType(int32_t type)
8234 {
8235
2/2
✓ Branch 0 taken 9788 times.
✓ Branch 1 taken 5907 times.
15695 switch(type)
8236 {
8237 case cSLASHNEXT:
8238 case cSLASHNEXTITEM:
8239 case cTALLGRASSNEXT:
8240 case cBUSHNEXT:
8241 case cSLASHNEXTTOUCHY:
8242 case cSLASHNEXTITEMTOUCHY:
8243 case cBUSHNEXTTOUCHY:
8244 5907 return true;
8245 }
8246
8247 9788 return false;
8248 15695 }
8249
8250 17546 bool isTouchyType(int32_t type)
8251 {
8252
2/2
✓ Branch 0 taken 6050 times.
✓ Branch 1 taken 11496 times.
17546 switch(type)
8253 {
8254 case cSLASHTOUCHY:
8255 case cSLASHITEMTOUCHY:
8256 case cBUSHTOUCHY:
8257 case cFLOWERSTOUCHY:
8258 case cTALLGRASSTOUCHY:
8259 case cSLASHNEXTTOUCHY:
8260 case cSLASHNEXTITEMTOUCHY:
8261 case cBUSHNEXTTOUCHY:
8262 11496 return true;
8263 }
8264
8265 6050 return false;
8266 17546 }
8267
8268 29373738 bool isCuttableType(int32_t type)
8269 {
8270
2/2
✓ Branch 0 taken 28924473 times.
✓ Branch 1 taken 449265 times.
29373738 switch(type)
8271 {
8272 case cSLASH:
8273 case cSLASHITEM:
8274 case cBUSH:
8275 case cFLOWERS:
8276 case cTALLGRASS:
8277 case cTALLGRASSNEXT:
8278 case cSLASHNEXT:
8279 case cSLASHNEXTITEM:
8280 case cBUSHNEXT:
8281
8282 case cSLASHTOUCHY:
8283 case cSLASHITEMTOUCHY:
8284 case cBUSHTOUCHY:
8285 case cFLOWERSTOUCHY:
8286 case cTALLGRASSTOUCHY:
8287 case cSLASHNEXTTOUCHY:
8288 case cSLASHNEXTITEMTOUCHY:
8289 case cBUSHNEXTTOUCHY:
8290 449265 return true;
8291 }
8292
8293 28924473 return false;
8294 29373738 }
8295
8296 17322 bool isCuttableItemType(int32_t type)
8297 {
8298
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 16898 times.
17322 switch(type)
8299 {
8300 case cSLASHITEM:
8301 case cBUSH:
8302 case cFLOWERS:
8303 case cTALLGRASS:
8304 case cTALLGRASSNEXT:
8305 case cSLASHNEXTITEM:
8306 case cBUSHNEXT:
8307
8308 case cSLASHITEMTOUCHY:
8309 case cBUSHTOUCHY:
8310 case cFLOWERSTOUCHY:
8311 case cTALLGRASSTOUCHY:
8312 case cSLASHNEXTITEMTOUCHY:
8313 case cBUSHNEXTTOUCHY:
8314 16898 return true;
8315 }
8316
8317 424 return false;
8318 17322 }
8319
8320 66 bool is_push(mapscr* m, int32_t pos)
8321 {
8322
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(m->sflag[pos]))
8323 return true;
8324 66 newcombo const& cmb = combobuf[m->data[pos]];
8325
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(cmb.flag))
8326 return true;
8327
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 52 times.
66 if(cmb.type == cPUSHBLOCK)
8328 14 return true;
8329
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
52 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8330 return true; //Counts as 'pushblock' flag
8331 52 return false;
8332 66 }
8333
8334 416 static std::map<int, screen_state_t> screen_states;
8335
8336 35855 std::map<int, screen_state_t>& get_screen_states()
8337 {
8338 35855 return screen_states;
8339 }
8340
8341 44191514 screen_state_t& get_screen_state(int screen)
8342 {
8343 44191514 return screen_states[screen];
8344 }
8345
8346 576 void clear_screen_states()
8347 {
8348 576 screen_states.clear();
8349 576 }
8350
8351 1439 void screen_item_set_state(int screen, ScreenItemState state)
8352 {
8353 1439 get_screen_state(screen).item_state = state;
8354 1439 }
8355
8356 37021 void mark_visited(int screen)
8357 {
8358
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 36546 times.
37021 if (screen < 0x80)
8359 {
8360
2/2
✓ Branch 0 taken 24611 times.
✓ Branch 1 taken 11935 times.
36546 if(DMaps[cur_dmap].flags&dmfVIEWMAP)
8361 11935 game->maps[mapind(cur_map, screen)] |= mVISITED;
8362
8363 36546 markBmap(-1, screen);
8364 36546 }
8365 37021 }
8366